source: trunk/gcc/libjava/java/security/SecureRandom.java

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 11.6 KB
Line 
1/* SecureRandom.java --- Secure Random class implmentation
2 Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38package java.security;
39
40import java.io.Serializable;
41import java.util.Random;
42import java.util.Enumeration;
43
44/**
45 SecureRandom is the class interface for using SecureRandom
46 providers. It provides an interface to the SecureRandomSpi
47 engine so that programmers can generate pseudo-random numbers.
48
49 @author Mark Benvenuto <ivymccough@worldnet.att.net>
50 */
51public class SecureRandom extends Random
52{
53 static final long serialVersionUID = 4940670005562187L;
54
55 //Serialized Field
56 long counter = 0; //Serialized
57 Provider provider = null;
58 byte[] randomBytes = null; //Always null
59 int randomBytesUsed = 0;
60 SecureRandomSpi secureRandomSpi = null;
61 byte[] state = null;
62
63 /**
64 Default constructor for SecureRandom. It constructs a
65 new SecureRandom by instantating the first SecureRandom
66 algorithm in the default security provier.
67
68 It is not seeded and should be seeded using setSeed or else
69 on the first call to getnextBytes it will force a seed.
70
71 It is maintained for backwards compatibility and programs
72 should use getInstance.
73 */
74 public SecureRandom()
75 {
76 Provider p[] = Security.getProviders();
77
78 //Format of Key: SecureRandom.algname
79 String key;
80
81 String classname = null;
82 int i, flag = 0;
83 Enumeration e;
84 for (i = 0; i < p.length; i++)
85 {
86 e = p[i].propertyNames();
87 while (e.hasMoreElements())
88 {
89 key = (String) e.nextElement();
90 if (key.startsWith("SECURERANDOM."))
91 {
92 if ((classname = p[i].getProperty(key)) != null)
93 {
94 try
95 {
96 secureRandomSpi = (SecureRandomSpi) Class.
97 forName(classname).newInstance();
98 provider = p[i];
99 return;
100 }
101 catch (Throwable ignore) { }
102 }
103 }
104 }
105 }
106
107 // Nothing found. Fall back to SHA1PRNG
108 secureRandomSpi = new gnu.java.security.provider.SHA1PRNG();
109 }
110
111 /**
112 A constructor for SecureRandom. It constructs a new
113 SecureRandom by instantating the first SecureRandom algorithm
114 in the default security provier.
115
116 It is seeded with the passed function and is useful if the user
117 has access to hardware random device (like a radiation detector).
118
119 It is maintained for backwards compatibility and programs
120 should use getInstance.
121
122 @param seed Seed bytes for class
123 */
124 public SecureRandom(byte[] seed)
125 {
126 this();
127 setSeed(seed);
128 }
129
130 /**
131 A constructor for SecureRandom. It constructs a new
132 SecureRandom using the specified SecureRandomSpi from
133 the specified security provier.
134
135 @param secureRandomSpi A SecureRandomSpi class
136 @param provider A Provider class
137 */
138 protected SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider)
139 {
140 this.secureRandomSpi = secureRandomSpi;
141 this.provider = provider;
142 }
143
144 /**
145 Returns an instance of a SecureRandom. It creates the class
146 for the specified algorithm if it exists from a provider.
147
148 @param algorithm A SecureRandom algorithm to use
149
150 @return Returns a new SecureRandom implmenting the chosen algorithm
151
152 @throws NoSuchAlgorithmException if the algorithm cannot be found
153 */
154 public static SecureRandom getInstance(String algorithm) throws
155 NoSuchAlgorithmException
156 {
157 Provider p[] = Security.getProviders();
158 for (int i = 0; i < p.length; i++)
159 {
160 try
161 {
162 return getInstance(algorithm, p[i]);
163 }
164 catch (NoSuchAlgorithmException ignored) { }
165 }
166
167 // None found.
168 throw new NoSuchAlgorithmException(algorithm);
169 }
170
171 /**
172 Returns an instance of a SecureRandom. It creates the class
173 for the specified algorithm from the specified provider.
174
175 @param algorithm A SecureRandom algorithm to use
176 @param provider A security provider to use
177
178 @return Returns a new SecureRandom implmenting the chosen algorithm
179
180 @throws NoSuchAlgorithmException if the algorithm cannot be found
181 @throws NoSuchProviderException if the provider cannot be found
182 */
183 public static SecureRandom getInstance(String algorithm,
184 String provider) throws
185 NoSuchAlgorithmException, NoSuchProviderException
186 {
187 Provider p = Security.getProvider(provider);
188 if (p == null)
189 throw new NoSuchProviderException();
190
191 return getInstance(algorithm, p);
192 }
193
194 /**
195 Returns an instance of a SecureRandom. It creates the class for
196 the specified algorithm from the given provider.
197
198 @param algorithm The SecureRandom algorithm to create.
199 @param provider The provider to get the instance from.
200
201 @throws NoSuchAlgorithmException If the algorithm cannot be found, or
202 if the class cannot be instantiated.
203 */
204 public static SecureRandom getInstance(String algorithm,
205 Provider provider) throws
206 NoSuchAlgorithmException
207 {
208 return getInstance(algorithm, provider, true);
209 }
210
211 /**
212 Creates the instance of SecureRandom, recursing to resolve aliases.
213
214 @param algorithm The SecureRandom algorithm to create.
215 @param provider The provider to get the implementation from.
216 @param recurse Whether or not to recurse to resolve aliases.
217
218 @throws NoSuchAlgorithmException If the algorithm cannot be found,
219 if there are too many aliases, or if the class cannot be
220 instantiated.
221 */
222 private static SecureRandom getInstance(String algorithm,
223 Provider provider,
224 boolean recurse)
225 throws NoSuchAlgorithmException
226 {
227 String msg = algorithm;
228 for (Enumeration e = provider.propertyNames(); e.hasMoreElements(); )
229 {
230 // We could replace the boolean with an integer, incrementing it
231 // every
232 String key = (String) e.nextElement();
233 if (key.startsWith("SECURERANDOM.")
234 && key.substring(13).equalsIgnoreCase(algorithm))
235 {
236 try
237 {
238 Class c = Class.forName(provider.getProperty(key));
239 return new SecureRandom((SecureRandomSpi) c.newInstance(),
240 provider);
241 }
242 catch (Throwable ignored) { }
243 }
244 else if (key.startsWith("ALG.ALIAS.SECURERANDOM.")
245 && key.substring(23).equalsIgnoreCase(algorithm) && recurse)
246 {
247 try
248 {
249 // First see if this alias refers to a class in this
250 // provider.
251 return getInstance(provider.getProperty(key), provider, false);
252 }
253 catch (NoSuchAlgorithmException nsae)
254 {
255 Provider[] provs = Security.getProviders();
256 for (int i = 0; i < provs.length; i++)
257 {
258 if (provs[i] == provider)
259 continue;
260 // Now try other providers for the implementation
261 try
262 {
263 return getInstance(provider.getProperty(key),
264 provs[i], false);
265 }
266 catch (NoSuchAlgorithmException nsae2)
267 {
268 msg = nsae2.getMessage();
269 }
270 }
271 }
272 }
273 }
274 throw new NoSuchAlgorithmException(algorithm);
275 }
276
277 /**
278 Returns the provider being used by the current SecureRandom class.
279
280 @return The provider from which this SecureRandom was attained
281 */
282 public final Provider getProvider()
283 {
284 return provider;
285 }
286
287 /**
288 Seeds the SecureRandom. The class is re-seeded for each call and
289 each seed builds on the previous seed so as not to weaken security.
290
291 @param seed seed bytes to seed with
292 */
293 public void setSeed(byte[] seed)
294 {
295 secureRandomSpi.engineSetSeed(seed);
296 }
297
298 /**
299 Seeds the SecureRandom. The class is re-seeded for each call and
300 each seed builds on the previous seed so as not to weaken security.
301
302 @param seed 8 seed bytes to seed with
303 */
304 public void setSeed(long seed)
305 {
306 // This particular setSeed will be called by Random.Random(), via
307 // our own constructor, before secureRandomSpi is initialized. In
308 // this case we can't call a method on secureRandomSpi, and we
309 // definitely don't want to throw a NullPointerException.
310 // Therefore we test.
311 if (secureRandomSpi != null)
312 {
313 byte tmp[] = { (byte) (0xff & (seed >> 56)),
314 (byte) (0xff & (seed >> 48)),
315 (byte) (0xff & (seed >> 40)),
316 (byte) (0xff & (seed >> 32)),
317 (byte) (0xff & (seed >> 24)),
318 (byte) (0xff & (seed >> 16)),
319 (byte) (0xff & (seed >> 8)),
320 (byte) (0xff & seed)
321 };
322 secureRandomSpi.engineSetSeed(tmp);
323 }
324 }
325
326 /**
327 Generates a user specified number of bytes. This function
328 is the basis for all the random functions.
329
330 @param bytes array to store generated bytes in
331 */
332 public void nextBytes(byte[] bytes)
333 {
334 randomBytesUsed += bytes.length;
335 counter++;
336 secureRandomSpi.engineNextBytes(bytes);
337 }
338
339 /**
340 Generates an integer containing the user specified
341 number of random bits. It is right justified and padded
342 with zeros.
343
344 @param numBits number of random bits to get, 0 <= numBits <= 32;
345
346 @return the random bits
347 */
348 protected final int next(int numBits)
349 {
350 if (numBits == 0)
351 return 0;
352
353 byte tmp[] = new byte[numBits / 8 + (1 * (numBits % 8))];
354
355 secureRandomSpi.engineNextBytes(tmp);
356 randomBytesUsed += tmp.length;
357 counter++;
358
359 int ret = 0;
360
361 for (int i = 0; i < tmp.length; i++)
362 ret |= (tmp[i] & 0xFF) << (8 * i);
363
364 long mask = (1L << numBits) - 1;
365 return (int) (ret & mask);
366 }
367
368 /**
369 Returns the given number of seed bytes. This method is
370 maintained only for backwards capability.
371
372 @param numBytes number of seed bytes to get
373
374 @return an array containing the seed bytes
375 */
376 public static byte[] getSeed(int numBytes)
377 {
378 byte tmp[] = new byte[numBytes];
379
380 new Random().nextBytes(tmp);
381 return tmp;
382 //return secureRandomSpi.engineGenerateSeed( numBytes );
383 }
384
385 /**
386 Returns the specified number of seed bytes.
387
388 @param numBytes number of seed bytes to get
389
390 @return an array containing the seed bytes
391 */
392 public byte[] generateSeed(int numBytes)
393 {
394 return secureRandomSpi.engineGenerateSeed(numBytes);
395 }
396
397}
Note: See TracBrowser for help on using the repository browser.