30 import java.security.*; |
30 import java.security.*; |
31 import java.security.interfaces.*; |
31 import java.security.interfaces.*; |
32 import java.security.spec.*; |
32 import java.security.spec.*; |
33 |
33 |
34 import sun.security.action.GetPropertyAction; |
34 import sun.security.action.GetPropertyAction; |
|
35 import sun.security.x509.AlgorithmId; |
|
36 import static sun.security.rsa.RSAUtil.KeyType; |
35 |
37 |
36 /** |
38 /** |
37 * KeyFactory for RSA keys. Keys must be instances of PublicKey or PrivateKey |
39 * KeyFactory for RSA keys, e.g. "RSA", "RSASSA-PSS". |
38 * and getAlgorithm() must return "RSA". For such keys, it supports conversion |
40 * Keys must be instances of PublicKey or PrivateKey |
|
41 * and getAlgorithm() must return a value which matches the type which are |
|
42 * specified during construction time of the KeyFactory object. |
|
43 * For such keys, it supports conversion |
39 * between the following: |
44 * between the following: |
40 * |
45 * |
41 * For public keys: |
46 * For public keys: |
42 * . PublicKey with an X.509 encoding |
47 * . PublicKey with an X.509 encoding |
43 * . RSAPublicKey |
48 * . RSAPublicKey |
56 * Note: as always, RSA keys should be at least 512 bits long |
61 * Note: as always, RSA keys should be at least 512 bits long |
57 * |
62 * |
58 * @since 1.5 |
63 * @since 1.5 |
59 * @author Andreas Sterbenz |
64 * @author Andreas Sterbenz |
60 */ |
65 */ |
61 public final class RSAKeyFactory extends KeyFactorySpi { |
66 public class RSAKeyFactory extends KeyFactorySpi { |
62 |
67 |
63 private static final Class<?> rsaPublicKeySpecClass = |
68 private static final Class<?> RSA_PUB_KEYSPEC_CLS = RSAPublicKeySpec.class; |
64 RSAPublicKeySpec.class; |
69 private static final Class<?> RSA_PRIV_KEYSPEC_CLS = |
65 private static final Class<?> rsaPrivateKeySpecClass = |
70 RSAPrivateKeySpec.class; |
66 RSAPrivateKeySpec.class; |
71 private static final Class<?> RSA_PRIVCRT_KEYSPEC_CLS = |
67 private static final Class<?> rsaPrivateCrtKeySpecClass = |
72 RSAPrivateCrtKeySpec.class; |
68 RSAPrivateCrtKeySpec.class; |
73 private static final Class<?> X509_KEYSPEC_CLS = X509EncodedKeySpec.class; |
69 |
74 private static final Class<?> PKCS8_KEYSPEC_CLS = PKCS8EncodedKeySpec.class; |
70 private static final Class<?> x509KeySpecClass = X509EncodedKeySpec.class; |
|
71 private static final Class<?> pkcs8KeySpecClass = PKCS8EncodedKeySpec.class; |
|
72 |
75 |
73 public static final int MIN_MODLEN = 512; |
76 public static final int MIN_MODLEN = 512; |
74 public static final int MAX_MODLEN = 16384; |
77 public static final int MAX_MODLEN = 16384; |
|
78 |
|
79 private final KeyType type; |
75 |
80 |
76 /* |
81 /* |
77 * If the modulus length is above this value, restrict the size of |
82 * If the modulus length is above this value, restrict the size of |
78 * the exponent to something that can be reasonably computed. We |
83 * the exponent to something that can be reasonably computed. We |
79 * could simply hardcode the exp len to something like 64 bits, but |
84 * could simply hardcode the exp len to something like 64 bits, but |
85 |
90 |
86 private static final boolean restrictExpLen = |
91 private static final boolean restrictExpLen = |
87 "true".equalsIgnoreCase(GetPropertyAction.privilegedGetProperty( |
92 "true".equalsIgnoreCase(GetPropertyAction.privilegedGetProperty( |
88 "sun.security.rsa.restrictRSAExponent", "true")); |
93 "sun.security.rsa.restrictRSAExponent", "true")); |
89 |
94 |
90 // instance used for static translateKey(); |
95 static RSAKeyFactory getInstance(KeyType type) { |
91 private static final RSAKeyFactory INSTANCE = new RSAKeyFactory(); |
96 return new RSAKeyFactory(type); |
92 |
97 } |
93 public RSAKeyFactory() { |
98 |
94 // empty |
99 // Internal utility method for checking key algorithm |
|
100 private static void checkKeyAlgo(Key key, String expectedAlg) |
|
101 throws InvalidKeyException { |
|
102 String keyAlg = key.getAlgorithm(); |
|
103 if (!(keyAlg.equalsIgnoreCase(expectedAlg))) { |
|
104 throw new InvalidKeyException("Expected a " + expectedAlg |
|
105 + " key, but got " + keyAlg); |
|
106 } |
95 } |
107 } |
96 |
108 |
97 /** |
109 /** |
98 * Static method to convert Key into an instance of RSAPublicKeyImpl |
110 * Static method to convert Key into an instance of RSAPublicKeyImpl |
99 * or RSAPrivate(Crt)KeyImpl. If the key is not an RSA key or cannot be |
111 * or RSAPrivate(Crt)KeyImpl. If the key is not an RSA key or cannot be |
169 " if modulus is greater than " + |
188 " if modulus is greater than " + |
170 MAX_MODLEN_RESTRICT_EXP + " bits"); |
189 MAX_MODLEN_RESTRICT_EXP + " bits"); |
171 } |
190 } |
172 } |
191 } |
173 |
192 |
|
193 // disallowed as KeyType is required |
|
194 private RSAKeyFactory() { |
|
195 this.type = KeyType.RSA; |
|
196 } |
|
197 |
|
198 public RSAKeyFactory(KeyType type) { |
|
199 this.type = type; |
|
200 } |
|
201 |
174 /** |
202 /** |
175 * Translate an RSA key into a SunRsaSign RSA key. If conversion is |
203 * Translate an RSA key into a SunRsaSign RSA key. If conversion is |
176 * not possible, throw an InvalidKeyException. |
204 * not possible, throw an InvalidKeyException. |
177 * See also JCA doc. |
205 * See also JCA doc. |
178 */ |
206 */ |
179 protected Key engineTranslateKey(Key key) throws InvalidKeyException { |
207 protected Key engineTranslateKey(Key key) throws InvalidKeyException { |
180 if (key == null) { |
208 if (key == null) { |
181 throw new InvalidKeyException("Key must not be null"); |
209 throw new InvalidKeyException("Key must not be null"); |
182 } |
210 } |
183 String keyAlg = key.getAlgorithm(); |
211 // ensure the key algorithm matches the current KeyFactory instance |
184 if (keyAlg.equals("RSA") == false) { |
212 checkKeyAlgo(key, type.keyAlgo()); |
185 throw new InvalidKeyException("Not an RSA key: " + keyAlg); |
213 |
|
214 // no translation needed if the key is already our own impl |
|
215 if ((key instanceof RSAPrivateKeyImpl) || |
|
216 (key instanceof RSAPrivateCrtKeyImpl) || |
|
217 (key instanceof RSAPublicKeyImpl)) { |
|
218 return key; |
186 } |
219 } |
187 if (key instanceof PublicKey) { |
220 if (key instanceof PublicKey) { |
188 return translatePublicKey((PublicKey)key); |
221 return translatePublicKey((PublicKey)key); |
189 } else if (key instanceof PrivateKey) { |
222 } else if (key instanceof PrivateKey) { |
190 return translatePrivateKey((PrivateKey)key); |
223 return translatePrivateKey((PrivateKey)key); |
219 |
252 |
220 // internal implementation of translateKey() for public keys. See JCA doc |
253 // internal implementation of translateKey() for public keys. See JCA doc |
221 private PublicKey translatePublicKey(PublicKey key) |
254 private PublicKey translatePublicKey(PublicKey key) |
222 throws InvalidKeyException { |
255 throws InvalidKeyException { |
223 if (key instanceof RSAPublicKey) { |
256 if (key instanceof RSAPublicKey) { |
224 if (key instanceof RSAPublicKeyImpl) { |
|
225 return key; |
|
226 } |
|
227 RSAPublicKey rsaKey = (RSAPublicKey)key; |
257 RSAPublicKey rsaKey = (RSAPublicKey)key; |
228 try { |
258 try { |
229 return new RSAPublicKeyImpl( |
259 return new RSAPublicKeyImpl( |
|
260 RSAUtil.createAlgorithmId(type, rsaKey.getParams()), |
230 rsaKey.getModulus(), |
261 rsaKey.getModulus(), |
231 rsaKey.getPublicExponent() |
262 rsaKey.getPublicExponent()); |
232 ); |
263 } catch (ProviderException e) { |
233 } catch (RuntimeException e) { |
|
234 // catch providers that incorrectly implement RSAPublicKey |
264 // catch providers that incorrectly implement RSAPublicKey |
235 throw new InvalidKeyException("Invalid key", e); |
265 throw new InvalidKeyException("Invalid key", e); |
236 } |
266 } |
237 } else if ("X.509".equals(key.getFormat())) { |
267 } else if ("X.509".equals(key.getFormat())) { |
238 byte[] encoded = key.getEncoded(); |
268 byte[] encoded = key.getEncoded(); |
239 return new RSAPublicKeyImpl(encoded); |
269 RSAPublicKey translated = new RSAPublicKeyImpl(encoded); |
|
270 // ensure the key algorithm matches the current KeyFactory instance |
|
271 checkKeyAlgo(translated, type.keyAlgo()); |
|
272 return translated; |
240 } else { |
273 } else { |
241 throw new InvalidKeyException("Public keys must be instance " |
274 throw new InvalidKeyException("Public keys must be instance " |
242 + "of RSAPublicKey or have X.509 encoding"); |
275 + "of RSAPublicKey or have X.509 encoding"); |
243 } |
276 } |
244 } |
277 } |
245 |
278 |
246 // internal implementation of translateKey() for private keys. See JCA doc |
279 // internal implementation of translateKey() for private keys. See JCA doc |
247 private PrivateKey translatePrivateKey(PrivateKey key) |
280 private PrivateKey translatePrivateKey(PrivateKey key) |
248 throws InvalidKeyException { |
281 throws InvalidKeyException { |
249 if (key instanceof RSAPrivateCrtKey) { |
282 if (key instanceof RSAPrivateCrtKey) { |
250 if (key instanceof RSAPrivateCrtKeyImpl) { |
|
251 return key; |
|
252 } |
|
253 RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key; |
283 RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)key; |
254 try { |
284 try { |
255 return new RSAPrivateCrtKeyImpl( |
285 return new RSAPrivateCrtKeyImpl( |
|
286 RSAUtil.createAlgorithmId(type, rsaKey.getParams()), |
256 rsaKey.getModulus(), |
287 rsaKey.getModulus(), |
257 rsaKey.getPublicExponent(), |
288 rsaKey.getPublicExponent(), |
258 rsaKey.getPrivateExponent(), |
289 rsaKey.getPrivateExponent(), |
259 rsaKey.getPrimeP(), |
290 rsaKey.getPrimeP(), |
260 rsaKey.getPrimeQ(), |
291 rsaKey.getPrimeQ(), |
261 rsaKey.getPrimeExponentP(), |
292 rsaKey.getPrimeExponentP(), |
262 rsaKey.getPrimeExponentQ(), |
293 rsaKey.getPrimeExponentQ(), |
263 rsaKey.getCrtCoefficient() |
294 rsaKey.getCrtCoefficient() |
264 ); |
295 ); |
265 } catch (RuntimeException e) { |
296 } catch (ProviderException e) { |
266 // catch providers that incorrectly implement RSAPrivateCrtKey |
297 // catch providers that incorrectly implement RSAPrivateCrtKey |
267 throw new InvalidKeyException("Invalid key", e); |
298 throw new InvalidKeyException("Invalid key", e); |
268 } |
299 } |
269 } else if (key instanceof RSAPrivateKey) { |
300 } else if (key instanceof RSAPrivateKey) { |
270 if (key instanceof RSAPrivateKeyImpl) { |
|
271 return key; |
|
272 } |
|
273 RSAPrivateKey rsaKey = (RSAPrivateKey)key; |
301 RSAPrivateKey rsaKey = (RSAPrivateKey)key; |
274 try { |
302 try { |
275 return new RSAPrivateKeyImpl( |
303 return new RSAPrivateKeyImpl( |
|
304 RSAUtil.createAlgorithmId(type, rsaKey.getParams()), |
276 rsaKey.getModulus(), |
305 rsaKey.getModulus(), |
277 rsaKey.getPrivateExponent() |
306 rsaKey.getPrivateExponent() |
278 ); |
307 ); |
279 } catch (RuntimeException e) { |
308 } catch (ProviderException e) { |
280 // catch providers that incorrectly implement RSAPrivateKey |
309 // catch providers that incorrectly implement RSAPrivateKey |
281 throw new InvalidKeyException("Invalid key", e); |
310 throw new InvalidKeyException("Invalid key", e); |
282 } |
311 } |
283 } else if ("PKCS#8".equals(key.getFormat())) { |
312 } else if ("PKCS#8".equals(key.getFormat())) { |
284 byte[] encoded = key.getEncoded(); |
313 byte[] encoded = key.getEncoded(); |
285 return RSAPrivateCrtKeyImpl.newKey(encoded); |
314 RSAPrivateKey translated = RSAPrivateCrtKeyImpl.newKey(encoded); |
|
315 // ensure the key algorithm matches the current KeyFactory instance |
|
316 checkKeyAlgo(translated, type.keyAlgo()); |
|
317 return translated; |
286 } else { |
318 } else { |
287 throw new InvalidKeyException("Private keys must be instance " |
319 throw new InvalidKeyException("Private keys must be instance " |
288 + "of RSAPrivate(Crt)Key or have PKCS#8 encoding"); |
320 + "of RSAPrivate(Crt)Key or have PKCS#8 encoding"); |
289 } |
321 } |
290 } |
322 } |
292 // internal implementation of generatePublic. See JCA doc |
324 // internal implementation of generatePublic. See JCA doc |
293 private PublicKey generatePublic(KeySpec keySpec) |
325 private PublicKey generatePublic(KeySpec keySpec) |
294 throws GeneralSecurityException { |
326 throws GeneralSecurityException { |
295 if (keySpec instanceof X509EncodedKeySpec) { |
327 if (keySpec instanceof X509EncodedKeySpec) { |
296 X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec; |
328 X509EncodedKeySpec x509Spec = (X509EncodedKeySpec)keySpec; |
297 return new RSAPublicKeyImpl(x509Spec.getEncoded()); |
329 RSAPublicKey generated = new RSAPublicKeyImpl(x509Spec.getEncoded()); |
|
330 // ensure the key algorithm matches the current KeyFactory instance |
|
331 checkKeyAlgo(generated, type.keyAlgo()); |
|
332 return generated; |
298 } else if (keySpec instanceof RSAPublicKeySpec) { |
333 } else if (keySpec instanceof RSAPublicKeySpec) { |
299 RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec; |
334 RSAPublicKeySpec rsaSpec = (RSAPublicKeySpec)keySpec; |
300 return new RSAPublicKeyImpl( |
335 try { |
301 rsaSpec.getModulus(), |
336 return new RSAPublicKeyImpl( |
302 rsaSpec.getPublicExponent() |
337 RSAUtil.createAlgorithmId(type, rsaSpec.getParams()), |
303 ); |
338 rsaSpec.getModulus(), |
|
339 rsaSpec.getPublicExponent() |
|
340 ); |
|
341 } catch (ProviderException e) { |
|
342 throw new InvalidKeySpecException(e); |
|
343 } |
304 } else { |
344 } else { |
305 throw new InvalidKeySpecException("Only RSAPublicKeySpec " |
345 throw new InvalidKeySpecException("Only RSAPublicKeySpec " |
306 + "and X509EncodedKeySpec supported for RSA public keys"); |
346 + "and X509EncodedKeySpec supported for RSA public keys"); |
307 } |
347 } |
308 } |
348 } |
310 // internal implementation of generatePrivate. See JCA doc |
350 // internal implementation of generatePrivate. See JCA doc |
311 private PrivateKey generatePrivate(KeySpec keySpec) |
351 private PrivateKey generatePrivate(KeySpec keySpec) |
312 throws GeneralSecurityException { |
352 throws GeneralSecurityException { |
313 if (keySpec instanceof PKCS8EncodedKeySpec) { |
353 if (keySpec instanceof PKCS8EncodedKeySpec) { |
314 PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec; |
354 PKCS8EncodedKeySpec pkcsSpec = (PKCS8EncodedKeySpec)keySpec; |
315 return RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded()); |
355 RSAPrivateKey generated = RSAPrivateCrtKeyImpl.newKey(pkcsSpec.getEncoded()); |
|
356 // ensure the key algorithm matches the current KeyFactory instance |
|
357 checkKeyAlgo(generated, type.keyAlgo()); |
|
358 return generated; |
316 } else if (keySpec instanceof RSAPrivateCrtKeySpec) { |
359 } else if (keySpec instanceof RSAPrivateCrtKeySpec) { |
317 RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec; |
360 RSAPrivateCrtKeySpec rsaSpec = (RSAPrivateCrtKeySpec)keySpec; |
318 return new RSAPrivateCrtKeyImpl( |
361 try { |
319 rsaSpec.getModulus(), |
362 return new RSAPrivateCrtKeyImpl( |
320 rsaSpec.getPublicExponent(), |
363 RSAUtil.createAlgorithmId(type, rsaSpec.getParams()), |
321 rsaSpec.getPrivateExponent(), |
364 rsaSpec.getModulus(), |
322 rsaSpec.getPrimeP(), |
365 rsaSpec.getPublicExponent(), |
323 rsaSpec.getPrimeQ(), |
366 rsaSpec.getPrivateExponent(), |
324 rsaSpec.getPrimeExponentP(), |
367 rsaSpec.getPrimeP(), |
325 rsaSpec.getPrimeExponentQ(), |
368 rsaSpec.getPrimeQ(), |
326 rsaSpec.getCrtCoefficient() |
369 rsaSpec.getPrimeExponentP(), |
327 ); |
370 rsaSpec.getPrimeExponentQ(), |
|
371 rsaSpec.getCrtCoefficient() |
|
372 ); |
|
373 } catch (ProviderException e) { |
|
374 throw new InvalidKeySpecException(e); |
|
375 } |
328 } else if (keySpec instanceof RSAPrivateKeySpec) { |
376 } else if (keySpec instanceof RSAPrivateKeySpec) { |
329 RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec; |
377 RSAPrivateKeySpec rsaSpec = (RSAPrivateKeySpec)keySpec; |
330 return new RSAPrivateKeyImpl( |
378 try { |
331 rsaSpec.getModulus(), |
379 return new RSAPrivateKeyImpl( |
332 rsaSpec.getPrivateExponent() |
380 RSAUtil.createAlgorithmId(type, rsaSpec.getParams()), |
333 ); |
381 rsaSpec.getModulus(), |
|
382 rsaSpec.getPrivateExponent() |
|
383 ); |
|
384 } catch (ProviderException e) { |
|
385 throw new InvalidKeySpecException(e); |
|
386 } |
334 } else { |
387 } else { |
335 throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec " |
388 throw new InvalidKeySpecException("Only RSAPrivate(Crt)KeySpec " |
336 + "and PKCS8EncodedKeySpec supported for RSA private keys"); |
389 + "and PKCS8EncodedKeySpec supported for RSA private keys"); |
337 } |
390 } |
338 } |
391 } |
347 } catch (InvalidKeyException e) { |
400 } catch (InvalidKeyException e) { |
348 throw new InvalidKeySpecException(e); |
401 throw new InvalidKeySpecException(e); |
349 } |
402 } |
350 if (key instanceof RSAPublicKey) { |
403 if (key instanceof RSAPublicKey) { |
351 RSAPublicKey rsaKey = (RSAPublicKey)key; |
404 RSAPublicKey rsaKey = (RSAPublicKey)key; |
352 if (rsaPublicKeySpecClass.isAssignableFrom(keySpec)) { |
405 if (RSA_PUB_KEYSPEC_CLS.isAssignableFrom(keySpec)) { |
353 return keySpec.cast(new RSAPublicKeySpec( |
406 return keySpec.cast(new RSAPublicKeySpec( |
354 rsaKey.getModulus(), |
407 rsaKey.getModulus(), |
355 rsaKey.getPublicExponent() |
408 rsaKey.getPublicExponent(), |
|
409 rsaKey.getParams() |
356 )); |
410 )); |
357 } else if (x509KeySpecClass.isAssignableFrom(keySpec)) { |
411 } else if (X509_KEYSPEC_CLS.isAssignableFrom(keySpec)) { |
358 return keySpec.cast(new X509EncodedKeySpec(key.getEncoded())); |
412 return keySpec.cast(new X509EncodedKeySpec(key.getEncoded())); |
359 } else { |
413 } else { |
360 throw new InvalidKeySpecException |
414 throw new InvalidKeySpecException |
361 ("KeySpec must be RSAPublicKeySpec or " |
415 ("KeySpec must be RSAPublicKeySpec or " |
362 + "X509EncodedKeySpec for RSA public keys"); |
416 + "X509EncodedKeySpec for RSA public keys"); |
363 } |
417 } |
364 } else if (key instanceof RSAPrivateKey) { |
418 } else if (key instanceof RSAPrivateKey) { |
365 if (pkcs8KeySpecClass.isAssignableFrom(keySpec)) { |
419 if (PKCS8_KEYSPEC_CLS.isAssignableFrom(keySpec)) { |
366 return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded())); |
420 return keySpec.cast(new PKCS8EncodedKeySpec(key.getEncoded())); |
367 } else if (rsaPrivateCrtKeySpecClass.isAssignableFrom(keySpec)) { |
421 } else if (RSA_PRIVCRT_KEYSPEC_CLS.isAssignableFrom(keySpec)) { |
368 if (key instanceof RSAPrivateCrtKey) { |
422 if (key instanceof RSAPrivateCrtKey) { |
369 RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey)key; |
423 RSAPrivateCrtKey crtKey = (RSAPrivateCrtKey)key; |
370 return keySpec.cast(new RSAPrivateCrtKeySpec( |
424 return keySpec.cast(new RSAPrivateCrtKeySpec( |
371 crtKey.getModulus(), |
425 crtKey.getModulus(), |
372 crtKey.getPublicExponent(), |
426 crtKey.getPublicExponent(), |
373 crtKey.getPrivateExponent(), |
427 crtKey.getPrivateExponent(), |
374 crtKey.getPrimeP(), |
428 crtKey.getPrimeP(), |
375 crtKey.getPrimeQ(), |
429 crtKey.getPrimeQ(), |
376 crtKey.getPrimeExponentP(), |
430 crtKey.getPrimeExponentP(), |
377 crtKey.getPrimeExponentQ(), |
431 crtKey.getPrimeExponentQ(), |
378 crtKey.getCrtCoefficient() |
432 crtKey.getCrtCoefficient(), |
|
433 crtKey.getParams() |
379 )); |
434 )); |
380 } else { |
435 } else { |
381 throw new InvalidKeySpecException |
436 throw new InvalidKeySpecException |
382 ("RSAPrivateCrtKeySpec can only be used with CRT keys"); |
437 ("RSAPrivateCrtKeySpec can only be used with CRT keys"); |
383 } |
438 } |
384 } else if (rsaPrivateKeySpecClass.isAssignableFrom(keySpec)) { |
439 } else if (RSA_PRIV_KEYSPEC_CLS.isAssignableFrom(keySpec)) { |
385 RSAPrivateKey rsaKey = (RSAPrivateKey)key; |
440 RSAPrivateKey rsaKey = (RSAPrivateKey)key; |
386 return keySpec.cast(new RSAPrivateKeySpec( |
441 return keySpec.cast(new RSAPrivateKeySpec( |
387 rsaKey.getModulus(), |
442 rsaKey.getModulus(), |
388 rsaKey.getPrivateExponent() |
443 rsaKey.getPrivateExponent(), |
|
444 rsaKey.getParams() |
389 )); |
445 )); |
390 } else { |
446 } else { |
391 throw new InvalidKeySpecException |
447 throw new InvalidKeySpecException |
392 ("KeySpec must be RSAPrivate(Crt)KeySpec or " |
448 ("KeySpec must be RSAPrivate(Crt)KeySpec or " |
393 + "PKCS8EncodedKeySpec for RSA private keys"); |
449 + "PKCS8EncodedKeySpec for RSA private keys"); |