31 import java.security.spec.AlgorithmParameterSpec; |
31 import java.security.spec.AlgorithmParameterSpec; |
32 import java.security.spec.RSAKeyGenParameterSpec; |
32 import java.security.spec.RSAKeyGenParameterSpec; |
33 |
33 |
34 import sun.security.jca.JCAUtil; |
34 import sun.security.jca.JCAUtil; |
35 import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE; |
35 import static sun.security.util.SecurityProviderConstants.DEF_RSA_KEY_SIZE; |
|
36 import static sun.security.util.SecurityProviderConstants.DEF_RSASSA_PSS_KEY_SIZE; |
|
37 import sun.security.x509.AlgorithmId; |
|
38 import static sun.security.rsa.RSAUtil.KeyType; |
36 |
39 |
37 /** |
40 /** |
38 * RSA keypair generation. Standard algorithm, minimum key length 512 bit. |
41 * RSA keypair generation. Standard algorithm, minimum key length 512 bit. |
39 * We generate two random primes until we find two where phi is relative |
42 * We generate two random primes until we find two where phi is relative |
40 * prime to the public exponent. Default exponent is 65537. It has only bit 0 |
43 * prime to the public exponent. Default exponent is 65537. It has only bit 0 |
41 * and bit 4 set, which makes it particularly efficient. |
44 * and bit 4 set, which makes it particularly efficient. |
42 * |
45 * |
43 * @since 1.5 |
46 * @since 1.5 |
44 * @author Andreas Sterbenz |
47 * @author Andreas Sterbenz |
45 */ |
48 */ |
46 public final class RSAKeyPairGenerator extends KeyPairGeneratorSpi { |
49 public abstract class RSAKeyPairGenerator extends KeyPairGeneratorSpi { |
47 |
50 |
48 // public exponent to use |
51 // public exponent to use |
49 private BigInteger publicExponent; |
52 private BigInteger publicExponent; |
50 |
53 |
51 // size of the key to generate, >= RSAKeyFactory.MIN_MODLEN |
54 // size of the key to generate, >= RSAKeyFactory.MIN_MODLEN |
52 private int keySize; |
55 private int keySize; |
53 |
56 |
|
57 private final KeyType type; |
|
58 private AlgorithmId rsaId; |
|
59 |
54 // PRNG to use |
60 // PRNG to use |
55 private SecureRandom random; |
61 private SecureRandom random; |
56 |
62 |
57 public RSAKeyPairGenerator() { |
63 RSAKeyPairGenerator(KeyType type, int defKeySize) { |
|
64 this.type = type; |
58 // initialize to default in case the app does not call initialize() |
65 // initialize to default in case the app does not call initialize() |
59 initialize(DEF_RSA_KEY_SIZE, null); |
66 initialize(defKeySize, null); |
60 } |
67 } |
61 |
68 |
62 // initialize the generator. See JCA doc |
69 // initialize the generator. See JCA doc |
63 public void initialize(int keySize, SecureRandom random) { |
70 public void initialize(int keySize, SecureRandom random) { |
64 |
|
65 // do not allow unreasonably small or large key sizes, |
|
66 // probably user error |
|
67 try { |
71 try { |
68 RSAKeyFactory.checkKeyLengths(keySize, RSAKeyGenParameterSpec.F4, |
72 initialize(new RSAKeyGenParameterSpec(keySize, |
69 512, 64 * 1024); |
73 RSAKeyGenParameterSpec.F4), null); |
70 } catch (InvalidKeyException e) { |
74 } catch (InvalidAlgorithmParameterException iape) { |
71 throw new InvalidParameterException(e.getMessage()); |
75 throw new InvalidParameterException(iape.getMessage()); |
72 } |
76 } |
73 |
|
74 this.keySize = keySize; |
|
75 this.random = random; |
|
76 this.publicExponent = RSAKeyGenParameterSpec.F4; |
|
77 } |
77 } |
78 |
78 |
79 // second initialize method. See JCA doc. |
79 // second initialize method. See JCA doc. |
80 public void initialize(AlgorithmParameterSpec params, SecureRandom random) |
80 public void initialize(AlgorithmParameterSpec params, SecureRandom random) |
81 throws InvalidAlgorithmParameterException { |
81 throws InvalidAlgorithmParameterException { |
82 |
|
83 if (params instanceof RSAKeyGenParameterSpec == false) { |
82 if (params instanceof RSAKeyGenParameterSpec == false) { |
84 throw new InvalidAlgorithmParameterException |
83 throw new InvalidAlgorithmParameterException |
85 ("Params must be instance of RSAKeyGenParameterSpec"); |
84 ("Params must be instance of RSAKeyGenParameterSpec"); |
86 } |
85 } |
87 |
86 |
88 RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params; |
87 RSAKeyGenParameterSpec rsaSpec = (RSAKeyGenParameterSpec)params; |
89 int tmpKeySize = rsaSpec.getKeysize(); |
88 int tmpKeySize = rsaSpec.getKeysize(); |
90 BigInteger tmpPublicExponent = rsaSpec.getPublicExponent(); |
89 BigInteger tmpPublicExponent = rsaSpec.getPublicExponent(); |
|
90 AlgorithmParameterSpec tmpParams = rsaSpec.getKeyParams(); |
91 |
91 |
92 if (tmpPublicExponent == null) { |
92 if (tmpPublicExponent == null) { |
93 tmpPublicExponent = RSAKeyGenParameterSpec.F4; |
93 tmpPublicExponent = RSAKeyGenParameterSpec.F4; |
94 } else { |
94 } else { |
95 if (tmpPublicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) { |
95 if (tmpPublicExponent.compareTo(RSAKeyGenParameterSpec.F0) < 0) { |
107 RSAKeyFactory.checkKeyLengths(tmpKeySize, tmpPublicExponent, |
107 RSAKeyFactory.checkKeyLengths(tmpKeySize, tmpPublicExponent, |
108 512, 64 * 1024); |
108 512, 64 * 1024); |
109 } catch (InvalidKeyException e) { |
109 } catch (InvalidKeyException e) { |
110 throw new InvalidAlgorithmParameterException( |
110 throw new InvalidAlgorithmParameterException( |
111 "Invalid key sizes", e); |
111 "Invalid key sizes", e); |
|
112 } |
|
113 |
|
114 try { |
|
115 this.rsaId = RSAUtil.createAlgorithmId(type, tmpParams); |
|
116 } catch (ProviderException e) { |
|
117 throw new InvalidAlgorithmParameterException( |
|
118 "Invalid key parameters", e); |
112 } |
119 } |
113 |
120 |
114 this.keySize = tmpKeySize; |
121 this.keySize = tmpKeySize; |
115 this.publicExponent = tmpPublicExponent; |
122 this.publicExponent = tmpPublicExponent; |
116 this.random = random; |
123 this.random = random; |
164 |
171 |
165 // crt coefficient coeff is the inverse of q mod p |
172 // crt coefficient coeff is the inverse of q mod p |
166 BigInteger coeff = q.modInverse(p); |
173 BigInteger coeff = q.modInverse(p); |
167 |
174 |
168 try { |
175 try { |
169 PublicKey publicKey = new RSAPublicKeyImpl(n, e); |
176 PublicKey publicKey = new RSAPublicKeyImpl(rsaId, n, e); |
170 PrivateKey privateKey = |
177 PrivateKey privateKey = new RSAPrivateCrtKeyImpl( |
171 new RSAPrivateCrtKeyImpl(n, e, d, p, q, pe, qe, coeff); |
178 rsaId, n, e, d, p, q, pe, qe, coeff); |
172 return new KeyPair(publicKey, privateKey); |
179 return new KeyPair(publicKey, privateKey); |
173 } catch (InvalidKeyException exc) { |
180 } catch (InvalidKeyException exc) { |
174 // invalid key exception only thrown for keys < 512 bit, |
181 // invalid key exception only thrown for keys < 512 bit, |
175 // will not happen here |
182 // will not happen here |
176 throw new RuntimeException(exc); |
183 throw new RuntimeException(exc); |
177 } |
184 } |
178 } |
185 } |
179 } |
186 } |
180 |
187 |
|
188 public static final class Legacy extends RSAKeyPairGenerator { |
|
189 public Legacy() { |
|
190 super(KeyType.RSA, DEF_RSA_KEY_SIZE); |
|
191 } |
|
192 } |
|
193 |
|
194 public static final class PSS extends RSAKeyPairGenerator { |
|
195 public PSS() { |
|
196 super(KeyType.PSS, DEF_RSASSA_PSS_KEY_SIZE); |
|
197 } |
|
198 } |
181 } |
199 } |