21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package javax.crypto;
27
28 import java.util.*;
29
30 import java.security.*;
31 import java.security.Provider.Service;
32 import java.security.spec.*;
33
34 import sun.security.jca.*;
35 import sun.security.jca.GetInstance.Instance;
36 import sun.security.util.Debug;
37
38 /**
39 * This class provides the functionality of a secret (symmetric) key generator.
40 *
41 * <p>Key generators are constructed using one of the <code>getInstance</code>
42 * class methods of this class.
43 *
44 * <p>KeyGenerator objects are reusable, i.e., after a key has been
45 * generated, the same KeyGenerator object can be re-used to generate further
46 * keys.
47 *
48 * <p>There are two ways to generate a key: in an algorithm-independent
49 * manner, and in an algorithm-specific manner.
50 * The only difference between the two is the initialization of the object:
51 *
52 * <ul>
53 * <li><b>Algorithm-Independent Initialization</b>
54 * <p>All key generators share the concepts of a <i>keysize</i> and a
55 * <i>source of randomness</i>.
56 * There is an
57 * {@link #init(int, java.security.SecureRandom) init}
58 * method in this KeyGenerator class that takes these two universally
59 * shared types of arguments. There is also one that takes just a
60 * <code>keysize</code> argument, and uses the SecureRandom implementation
61 * of the highest-priority installed provider as the source of randomness
62 * (or a system-provided source of randomness if none of the installed
63 * providers supply a SecureRandom implementation), and one that takes just a
64 * source of randomness.
65 *
66 * <p>Since no other parameters are specified when you call the above
67 * algorithm-independent <code>init</code> methods, it is up to the
68 * provider what to do about the algorithm-specific parameters (if any) to be
69 * associated with each of the keys.
70 *
71 * <li><b>Algorithm-Specific Initialization</b>
72 * <p>For situations where a set of algorithm-specific parameters already
73 * exists, there are two
74 * {@link #init(java.security.spec.AlgorithmParameterSpec) init}
75 * methods that have an <code>AlgorithmParameterSpec</code>
76 * argument. One also has a <code>SecureRandom</code> argument, while the
77 * other uses the SecureRandom implementation
78 * of the highest-priority installed provider as the source of randomness
79 * (or a system-provided source of randomness if none of the installed
80 * providers supply a SecureRandom implementation).
81 * </ul>
82 *
83 * <p>In case the client does not explicitly initialize the KeyGenerator
84 * (via a call to an <code>init</code> method), each provider must
85 * supply (and document) a default initialization.
86 *
87 * <p> Every implementation of the Java platform is required to support the
88 * following standard <code>KeyGenerator</code> algorithms with the keysizes in
89 * parentheses:
90 * <ul>
91 * <li><tt>AES</tt> (128)</li>
92 * <li><tt>DES</tt> (56)</li>
93 * <li><tt>DESede</tt> (168)</li>
94 * <li><tt>HmacSHA1</tt></li>
95 * <li><tt>HmacSHA256</tt></li>
96 * </ul>
97 * These algorithms are described in the <a href=
98 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
99 * KeyGenerator section</a> of the
100 * Java Cryptography Architecture Standard Algorithm Name Documentation.
101 * Consult the release documentation for your implementation to see if any
102 * other algorithms are supported.
103 *
104 * @author Jan Luehe
105 *
106 * @see SecretKey
107 * @since 1.4
108 */
109
110 public class KeyGenerator {
111
112 private static final Debug pdebug =
113 Debug.getInstance("provider", "Provider");
114 private static final boolean skipDebug =
115 Debug.isOn("engine=") && !Debug.isOn("keygenerator");
160
161 private KeyGenerator(String algorithm) throws NoSuchAlgorithmException {
162 this.algorithm = algorithm;
163 List<Service> list =
164 GetInstance.getServices("KeyGenerator", algorithm);
165 serviceIterator = list.iterator();
166 initType = I_NONE;
167 // fetch and instantiate initial spi
168 if (nextSpi(null, false) == null) {
169 throw new NoSuchAlgorithmException
170 (algorithm + " KeyGenerator not available");
171 }
172
173 if (!skipDebug && pdebug != null) {
174 pdebug.println("KeyGenerator." + algorithm + " algorithm from: " +
175 this.provider.getName());
176 }
177 }
178
179 /**
180 * Returns the algorithm name of this <code>KeyGenerator</code> object.
181 *
182 * <p>This is the same name that was specified in one of the
183 * <code>getInstance</code> calls that created this
184 * <code>KeyGenerator</code> object.
185 *
186 * @return the algorithm name of this <code>KeyGenerator</code> object.
187 */
188 public final String getAlgorithm() {
189 return this.algorithm;
190 }
191
192 /**
193 * Returns a <code>KeyGenerator</code> object that generates secret keys
194 * for the specified algorithm.
195 *
196 * <p> This method traverses the list of registered security Providers,
197 * starting with the most preferred Provider.
198 * A new KeyGenerator object encapsulating the
199 * KeyGeneratorSpi implementation from the first
200 * Provider that supports the specified algorithm is returned.
201 *
202 * <p> Note that the list of registered providers may be retrieved via
203 * the {@link Security#getProviders() Security.getProviders()} method.
204 *
205 * @param algorithm the standard name of the requested key algorithm.
206 * See the KeyGenerator section in the <a href=
207 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
208 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
209 * for information about standard algorithm names.
210 *
211 * @return the new <code>KeyGenerator</code> object.
212 *
213 * @exception NullPointerException if the specified algorithm is null.
214 *
215 * @exception NoSuchAlgorithmException if no Provider supports a
216 * KeyGeneratorSpi implementation for the
217 * specified algorithm.
218 *
219 * @see java.security.Provider
220 */
221 public static final KeyGenerator getInstance(String algorithm)
222 throws NoSuchAlgorithmException {
223 return new KeyGenerator(algorithm);
224 }
225
226 /**
227 * Returns a <code>KeyGenerator</code> object that generates secret keys
228 * for the specified algorithm.
229 *
230 * <p> A new KeyGenerator object encapsulating the
231 * KeyGeneratorSpi implementation from the specified provider
232 * is returned. The specified provider must be registered
233 * in the security provider list.
234 *
235 * <p> Note that the list of registered providers may be retrieved via
236 * the {@link Security#getProviders() Security.getProviders()} method.
237 *
238 * @param algorithm the standard name of the requested key algorithm.
239 * See the KeyGenerator section in the <a href=
240 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
241 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
242 * for information about standard algorithm names.
243 *
244 * @param provider the name of the provider.
245 *
246 * @return the new <code>KeyGenerator</code> object.
247 *
248 * @exception NullPointerException if the specified algorithm is null.
249 *
250 * @exception NoSuchAlgorithmException if a KeyGeneratorSpi
251 * implementation for the specified algorithm is not
252 * available from the specified provider.
253 *
254 * @exception NoSuchProviderException if the specified provider is not
255 * registered in the security provider list.
256 *
257 * @exception IllegalArgumentException if the <code>provider</code>
258 * is null or empty.
259 *
260 * @see java.security.Provider
261 */
262 public static final KeyGenerator getInstance(String algorithm,
263 String provider) throws NoSuchAlgorithmException,
264 NoSuchProviderException {
265 Instance instance = JceSecurity.getInstance("KeyGenerator",
266 KeyGeneratorSpi.class, algorithm, provider);
267 return new KeyGenerator((KeyGeneratorSpi)instance.impl,
268 instance.provider, algorithm);
269 }
270
271 /**
272 * Returns a <code>KeyGenerator</code> object that generates secret keys
273 * for the specified algorithm.
274 *
275 * <p> A new KeyGenerator object encapsulating the
276 * KeyGeneratorSpi implementation from the specified Provider
277 * object is returned. Note that the specified Provider object
278 * does not have to be registered in the provider list.
279 *
280 * @param algorithm the standard name of the requested key algorithm.
281 * See the KeyGenerator section in the <a href=
282 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
283 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
284 * for information about standard algorithm names.
285 *
286 * @param provider the provider.
287 *
288 * @return the new <code>KeyGenerator</code> object.
289 *
290 * @exception NullPointerException if the specified algorithm is null.
291 *
292 * @exception NoSuchAlgorithmException if a KeyGeneratorSpi
293 * implementation for the specified algorithm is not available
294 * from the specified Provider object.
295 *
296 * @exception IllegalArgumentException if the <code>provider</code>
297 * is null.
298 *
299 * @see java.security.Provider
300 */
301 public static final KeyGenerator getInstance(String algorithm,
302 Provider provider) throws NoSuchAlgorithmException {
303 Instance instance = JceSecurity.getInstance("KeyGenerator",
304 KeyGeneratorSpi.class, algorithm, provider);
305 return new KeyGenerator((KeyGeneratorSpi)instance.impl,
306 instance.provider, algorithm);
307 }
308
309 /**
310 * Returns the provider of this <code>KeyGenerator</code> object.
311 *
312 * @return the provider of this <code>KeyGenerator</code> object
313 */
314 public final Provider getProvider() {
315 synchronized (lock) {
316 disableFailover();
317 return provider;
318 }
319 }
320
321 /**
322 * Update the active spi of this class and return the next
323 * implementation for failover. If no more implementations are
324 * available, this method returns null. However, the active spi of
325 * this class is never set to null.
326 */
327 private KeyGeneratorSpi nextSpi(KeyGeneratorSpi oldSpi,
328 boolean reinit) {
329 synchronized (lock) {
330 // somebody else did a failover concurrently
331 // try that spi now
332 if ((oldSpi != null) && (oldSpi != spi)) {
420 * SecureRandom, a system-provided source of randomness will be used.)
421 *
422 * @param params the key generation parameters
423 *
424 * @exception InvalidAlgorithmParameterException if the given parameters
425 * are inappropriate for this key generator
426 */
427 public final void init(AlgorithmParameterSpec params)
428 throws InvalidAlgorithmParameterException
429 {
430 init(params, JceSecurity.RANDOM);
431 }
432
433 /**
434 * Initializes this key generator with the specified parameter
435 * set and a user-provided source of randomness.
436 *
437 * @param params the key generation parameters
438 * @param random the source of randomness for this key generator
439 *
440 * @exception InvalidAlgorithmParameterException if <code>params</code> is
441 * inappropriate for this key generator
442 */
443 public final void init(AlgorithmParameterSpec params, SecureRandom random)
444 throws InvalidAlgorithmParameterException
445 {
446 if (serviceIterator == null) {
447 spi.engineInit(params, random);
448 return;
449 }
450 Exception failure = null;
451 KeyGeneratorSpi mySpi = spi;
452 do {
453 try {
454 mySpi.engineInit(params, random);
455 initType = I_PARAMS;
456 initKeySize = 0;
457 initParams = params;
458 initRandom = random;
459 return;
460 } catch (Exception e) {
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package javax.crypto;
27
28 import java.util.*;
29
30 import java.security.*;
31 import java.security.Provider.Service;
32 import java.security.spec.*;
33
34 import sun.security.jca.*;
35 import sun.security.jca.GetInstance.Instance;
36 import sun.security.util.Debug;
37
38 /**
39 * This class provides the functionality of a secret (symmetric) key generator.
40 *
41 * <p>Key generators are constructed using one of the {@code getInstance}
42 * class methods of this class.
43 *
44 * <p>KeyGenerator objects are reusable, i.e., after a key has been
45 * generated, the same KeyGenerator object can be re-used to generate further
46 * keys.
47 *
48 * <p>There are two ways to generate a key: in an algorithm-independent
49 * manner, and in an algorithm-specific manner.
50 * The only difference between the two is the initialization of the object:
51 *
52 * <ul>
53 * <li><b>Algorithm-Independent Initialization</b>
54 * <p>All key generators share the concepts of a <i>keysize</i> and a
55 * <i>source of randomness</i>.
56 * There is an
57 * {@link #init(int, java.security.SecureRandom) init}
58 * method in this KeyGenerator class that takes these two universally
59 * shared types of arguments. There is also one that takes just a
60 * {@code keysize} argument, and uses the SecureRandom implementation
61 * of the highest-priority installed provider as the source of randomness
62 * (or a system-provided source of randomness if none of the installed
63 * providers supply a SecureRandom implementation), and one that takes just a
64 * source of randomness.
65 *
66 * <p>Since no other parameters are specified when you call the above
67 * algorithm-independent {@code init} methods, it is up to the
68 * provider what to do about the algorithm-specific parameters (if any) to be
69 * associated with each of the keys.
70 *
71 * <li><b>Algorithm-Specific Initialization</b>
72 * <p>For situations where a set of algorithm-specific parameters already
73 * exists, there are two
74 * {@link #init(java.security.spec.AlgorithmParameterSpec) init}
75 * methods that have an {@code AlgorithmParameterSpec}
76 * argument. One also has a {@code SecureRandom} argument, while the
77 * other uses the SecureRandom implementation
78 * of the highest-priority installed provider as the source of randomness
79 * (or a system-provided source of randomness if none of the installed
80 * providers supply a SecureRandom implementation).
81 * </ul>
82 *
83 * <p>In case the client does not explicitly initialize the KeyGenerator
84 * (via a call to an {@code init} method), each provider must
85 * supply (and document) a default initialization.
86 *
87 * <p> Every implementation of the Java platform is required to support the
88 * following standard {@code KeyGenerator} algorithms with the keysizes in
89 * parentheses:
90 * <ul>
91 * <li>{@code AES} (128)</li>
92 * <li>{@code DES} (56)</li>
93 * <li>{@code DESede} (168)</li>
94 * <li>{@code HmacSHA1}</li>
95 * <li>{@code HmacSHA256}</li>
96 * </ul>
97 * These algorithms are described in the <a href=
98 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
99 * KeyGenerator section</a> of the
100 * Java Cryptography Architecture Standard Algorithm Name Documentation.
101 * Consult the release documentation for your implementation to see if any
102 * other algorithms are supported.
103 *
104 * @author Jan Luehe
105 *
106 * @see SecretKey
107 * @since 1.4
108 */
109
110 public class KeyGenerator {
111
112 private static final Debug pdebug =
113 Debug.getInstance("provider", "Provider");
114 private static final boolean skipDebug =
115 Debug.isOn("engine=") && !Debug.isOn("keygenerator");
160
161 private KeyGenerator(String algorithm) throws NoSuchAlgorithmException {
162 this.algorithm = algorithm;
163 List<Service> list =
164 GetInstance.getServices("KeyGenerator", algorithm);
165 serviceIterator = list.iterator();
166 initType = I_NONE;
167 // fetch and instantiate initial spi
168 if (nextSpi(null, false) == null) {
169 throw new NoSuchAlgorithmException
170 (algorithm + " KeyGenerator not available");
171 }
172
173 if (!skipDebug && pdebug != null) {
174 pdebug.println("KeyGenerator." + algorithm + " algorithm from: " +
175 this.provider.getName());
176 }
177 }
178
179 /**
180 * Returns the algorithm name of this {@code KeyGenerator} object.
181 *
182 * <p>This is the same name that was specified in one of the
183 * {@code getInstance} calls that created this
184 * {@code KeyGenerator} object.
185 *
186 * @return the algorithm name of this {@code KeyGenerator} object.
187 */
188 public final String getAlgorithm() {
189 return this.algorithm;
190 }
191
192 /**
193 * Returns a {@code KeyGenerator} object that generates secret keys
194 * for the specified algorithm.
195 *
196 * <p> This method traverses the list of registered security Providers,
197 * starting with the most preferred Provider.
198 * A new KeyGenerator object encapsulating the
199 * KeyGeneratorSpi implementation from the first
200 * Provider that supports the specified algorithm is returned.
201 *
202 * <p> Note that the list of registered providers may be retrieved via
203 * the {@link Security#getProviders() Security.getProviders()} method.
204 *
205 * @param algorithm the standard name of the requested key algorithm.
206 * See the KeyGenerator section in the <a href=
207 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
208 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
209 * for information about standard algorithm names.
210 *
211 * @return the new {@code KeyGenerator} object.
212 *
213 * @exception NullPointerException if the specified algorithm is null.
214 *
215 * @exception NoSuchAlgorithmException if no Provider supports a
216 * KeyGeneratorSpi implementation for the
217 * specified algorithm.
218 *
219 * @see java.security.Provider
220 */
221 public static final KeyGenerator getInstance(String algorithm)
222 throws NoSuchAlgorithmException {
223 return new KeyGenerator(algorithm);
224 }
225
226 /**
227 * Returns a {@code KeyGenerator} object that generates secret keys
228 * for the specified algorithm.
229 *
230 * <p> A new KeyGenerator object encapsulating the
231 * KeyGeneratorSpi implementation from the specified provider
232 * is returned. The specified provider must be registered
233 * in the security provider list.
234 *
235 * <p> Note that the list of registered providers may be retrieved via
236 * the {@link Security#getProviders() Security.getProviders()} method.
237 *
238 * @param algorithm the standard name of the requested key algorithm.
239 * See the KeyGenerator section in the <a href=
240 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
241 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
242 * for information about standard algorithm names.
243 *
244 * @param provider the name of the provider.
245 *
246 * @return the new {@code KeyGenerator} object.
247 *
248 * @exception NullPointerException if the specified algorithm is null.
249 *
250 * @exception NoSuchAlgorithmException if a KeyGeneratorSpi
251 * implementation for the specified algorithm is not
252 * available from the specified provider.
253 *
254 * @exception NoSuchProviderException if the specified provider is not
255 * registered in the security provider list.
256 *
257 * @exception IllegalArgumentException if the {@code provider}
258 * is null or empty.
259 *
260 * @see java.security.Provider
261 */
262 public static final KeyGenerator getInstance(String algorithm,
263 String provider) throws NoSuchAlgorithmException,
264 NoSuchProviderException {
265 Instance instance = JceSecurity.getInstance("KeyGenerator",
266 KeyGeneratorSpi.class, algorithm, provider);
267 return new KeyGenerator((KeyGeneratorSpi)instance.impl,
268 instance.provider, algorithm);
269 }
270
271 /**
272 * Returns a {@code KeyGenerator} object that generates secret keys
273 * for the specified algorithm.
274 *
275 * <p> A new KeyGenerator object encapsulating the
276 * KeyGeneratorSpi implementation from the specified Provider
277 * object is returned. Note that the specified Provider object
278 * does not have to be registered in the provider list.
279 *
280 * @param algorithm the standard name of the requested key algorithm.
281 * See the KeyGenerator section in the <a href=
282 * "{@docRoot}/../technotes/guides/security/StandardNames.html#KeyGenerator">
283 * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
284 * for information about standard algorithm names.
285 *
286 * @param provider the provider.
287 *
288 * @return the new {@code KeyGenerator} object.
289 *
290 * @exception NullPointerException if the specified algorithm is null.
291 *
292 * @exception NoSuchAlgorithmException if a KeyGeneratorSpi
293 * implementation for the specified algorithm is not available
294 * from the specified Provider object.
295 *
296 * @exception IllegalArgumentException if the {@code provider}
297 * is null.
298 *
299 * @see java.security.Provider
300 */
301 public static final KeyGenerator getInstance(String algorithm,
302 Provider provider) throws NoSuchAlgorithmException {
303 Instance instance = JceSecurity.getInstance("KeyGenerator",
304 KeyGeneratorSpi.class, algorithm, provider);
305 return new KeyGenerator((KeyGeneratorSpi)instance.impl,
306 instance.provider, algorithm);
307 }
308
309 /**
310 * Returns the provider of this {@code KeyGenerator} object.
311 *
312 * @return the provider of this {@code KeyGenerator} object
313 */
314 public final Provider getProvider() {
315 synchronized (lock) {
316 disableFailover();
317 return provider;
318 }
319 }
320
321 /**
322 * Update the active spi of this class and return the next
323 * implementation for failover. If no more implementations are
324 * available, this method returns null. However, the active spi of
325 * this class is never set to null.
326 */
327 private KeyGeneratorSpi nextSpi(KeyGeneratorSpi oldSpi,
328 boolean reinit) {
329 synchronized (lock) {
330 // somebody else did a failover concurrently
331 // try that spi now
332 if ((oldSpi != null) && (oldSpi != spi)) {
420 * SecureRandom, a system-provided source of randomness will be used.)
421 *
422 * @param params the key generation parameters
423 *
424 * @exception InvalidAlgorithmParameterException if the given parameters
425 * are inappropriate for this key generator
426 */
427 public final void init(AlgorithmParameterSpec params)
428 throws InvalidAlgorithmParameterException
429 {
430 init(params, JceSecurity.RANDOM);
431 }
432
433 /**
434 * Initializes this key generator with the specified parameter
435 * set and a user-provided source of randomness.
436 *
437 * @param params the key generation parameters
438 * @param random the source of randomness for this key generator
439 *
440 * @exception InvalidAlgorithmParameterException if {@code params} is
441 * inappropriate for this key generator
442 */
443 public final void init(AlgorithmParameterSpec params, SecureRandom random)
444 throws InvalidAlgorithmParameterException
445 {
446 if (serviceIterator == null) {
447 spi.engineInit(params, random);
448 return;
449 }
450 Exception failure = null;
451 KeyGeneratorSpi mySpi = spi;
452 do {
453 try {
454 mySpi.engineInit(params, random);
455 initType = I_PARAMS;
456 initKeySize = 0;
457 initParams = params;
458 initRandom = random;
459 return;
460 } catch (Exception e) {
|