source: trunk/src/gcc/libjava/java/security/SecureRandom.java@ 154

Last change on this file since 154 was 2, checked in by bird, 23 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 10.4 KB
Line 
1/* SecureRandom.java --- Secure Random class implmentation
2 Copyright (C) 1999, 2001 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;
39import java.io.Serializable;
40import java.util.Random;
41import java.util.Enumeration;
42
43/**
44 SecureRandom is the class interface for using SecureRandom
45 providers. It provides an interface to the SecureRandomSpi
46 engine so that programmers can generate pseudo-random numbers.
47
48 @author Mark Benvenuto <[email protected]>
49 */
50public class SecureRandom extends Random
51{
52 //Serialized Field
53 long counter = 0; //Serialized
54 MessageDigest digest = null;
55 Provider provider = null;
56 byte[] randomBytes = null; //Always null
57 int randomBytesUsed = 0;
58 SecureRandomSpi secureRandomSpi = null;
59 byte[] state = null;
60
61 /**
62 Default constructor for SecureRandom. It constructs a
63 new SecureRandom by instantating the first SecureRandom
64 algorithm in the default security provier.
65
66 It is not seeded and should be seeded using setSeed or else
67 on the first call to getnextBytes it will force a seed.
68
69 It is maintained for backwards compatibility and programs
70 should use getInstance.
71 */
72 public SecureRandom()
73 {
74 Provider p[] = Security.getProviders();
75
76 //Format of Key: SecureRandom.algname
77 String key;
78
79 String classname = null;
80 int i, flag = 0;
81 Enumeration e;
82 for (i = 0; i < p.length; i++)
83 {
84 e = p[i].propertyNames();
85 while (e.hasMoreElements())
86 {
87 key = (String) e.nextElement();
88 if (key.startsWith("SecureRandom."))
89 if ((classname = p[i].getProperty(key)) != null)
90 break;
91 }
92 if (classname != null)
93 break;
94 }
95
96 //if( classname == null)
97 // throw new NoSuchAlgorithmException();
98
99 try
100 {
101 this.secureRandomSpi =
102 (SecureRandomSpi) Class.forName(classname).newInstance();
103
104 //s.algorithm = algorithm;
105 this.provider = p[i];
106 }
107 catch (ClassNotFoundException cnfe)
108 {
109 //throw new NoSuchAlgorithmException("Class not found");
110 }
111 catch (InstantiationException ie)
112 {
113 //throw new NoSuchAlgorithmException("Class instantiation failed");
114 }
115 catch (IllegalAccessException iae)
116 {
117 //throw new NoSuchAlgorithmException("Illegal Access");
118 }
119 }
120
121 /**
122 A constructor for SecureRandom. It constructs a new
123 SecureRandom by instantating the first SecureRandom algorithm
124 in the default security provier.
125
126 It is seeded with the passed function and is useful if the user
127 has access to hardware random device (like a radiation detector).
128
129 It is maintained for backwards compatibility and programs
130 should use getInstance.
131
132 @param seed Seed bytes for class
133 */
134 public SecureRandom(byte[] seed)
135 {
136 this();
137 setSeed(seed);
138 }
139
140 /**
141 A constructor for SecureRandom. It constructs a new
142 SecureRandom using the specified SecureRandomSpi from
143 the specified security provier.
144
145 @param secureRandomSpi A SecureRandomSpi class
146 @param provider A Provider class
147 */
148 protected SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider)
149 {
150 this.secureRandomSpi = secureRandomSpi;
151 this.provider = provider;
152 }
153
154 /**
155 Returns an instance of a SecureRandom. It creates the class
156 for the specified algorithm if it exists from a provider.
157
158 @param algorithm A SecureRandom algorithm to use
159
160 @return Returns a new SecureRandom implmenting the chosen algorithm
161
162 @throws NoSuchAlgorithmException if the algorithm cannot be found
163 */
164 public static SecureRandom getInstance(String algorithm) throws
165 NoSuchAlgorithmException
166 {
167 Provider p[] = Security.getProviders();
168
169 //Format of Key: SecureRandom.algname
170 StringBuffer key = new StringBuffer("SecureRandom.");
171 key.append(algorithm);
172
173 String classname = null;
174 int i;
175 for (i = 0; i < p.length; i++)
176 {
177 if ((classname = p[i].getProperty(key.toString())) != null)
178 break;
179 }
180
181 if (classname == null)
182 throw new NoSuchAlgorithmException();
183
184 try
185 {
186 return new SecureRandom((SecureRandomSpi) Class.forName(classname).
187 newInstance(), p[i]);
188 }
189 catch (ClassNotFoundException cnfe)
190 {
191 throw new NoSuchAlgorithmException("Class not found");
192 }
193 catch (InstantiationException ie)
194 {
195 throw new NoSuchAlgorithmException("Class instantiation failed");
196 }
197 catch (IllegalAccessException iae)
198 {
199 throw new NoSuchAlgorithmException("Illegal Access");
200 }
201
202 }
203
204 /**
205 Returns an instance of a SecureRandom. It creates the class
206 for the specified algorithm from the specified provider.
207
208 @param algorithm A SecureRandom algorithm to use
209 @param provider A security provider to use
210
211 @return Returns a new SecureRandom implmenting the chosen algorithm
212
213 @throws NoSuchAlgorithmException if the algorithm cannot be found
214 @throws NoSuchProviderException if the provider cannot be found
215 */
216 public static SecureRandom getInstance(String algorithm,
217 String provider) throws
218 NoSuchAlgorithmException, NoSuchProviderException
219 {
220 Provider p = Security.getProvider(provider);
221 if (p == null)
222 throw new NoSuchProviderException();
223
224 //Format of Key: SecureRandom.algName
225 StringBuffer key = new StringBuffer("SecureRandom.");
226 key.append(algorithm);
227
228 String classname = p.getProperty(key.toString());
229 if (classname == null)
230 throw new NoSuchAlgorithmException();
231
232 try
233 {
234 return new SecureRandom((SecureRandomSpi) Class.forName(classname).
235 newInstance(), p);
236 }
237 catch (ClassNotFoundException cnfe)
238 {
239 throw new NoSuchAlgorithmException("Class not found");
240 }
241 catch (InstantiationException ie)
242 {
243 throw new NoSuchAlgorithmException("Class instantiation failed");
244 }
245 catch (IllegalAccessException iae)
246 {
247 throw new NoSuchAlgorithmException("Illegal Access");
248 }
249
250 }
251
252 /**
253 Returns the provider being used by the current SecureRandom class.
254
255 @return The provider from which this SecureRandom was attained
256 */
257 public final Provider getProvider()
258 {
259 return provider;
260 }
261
262 /**
263 Seeds the SecureRandom. The class is re-seeded for each call and
264 each seed builds on the previous seed so as not to weaken security.
265
266 @param seed seed bytes to seed with
267 */
268 public void setSeed(byte[] seed)
269 {
270 secureRandomSpi.engineSetSeed(seed);
271 }
272
273 /**
274 Seeds the SecureRandom. The class is re-seeded for each call and
275 each seed builds on the previous seed so as not to weaken security.
276
277 @param seed 8 seed bytes to seed with
278 */
279 public void setSeed(long seed)
280 {
281 // This particular setSeed will be called by Random.Random(), via
282 // our own constructor, before secureRandomSpi is initialized. In
283 // this case we can't call a method on secureRandomSpi, and we
284 // definitely don't want to throw a NullPointerException.
285 // Therefore we test.
286 if (secureRandomSpi != null)
287 {
288 byte tmp[] = { (byte) (0xff & (seed >> 56)),
289 (byte) (0xff & (seed >> 48)),
290 (byte) (0xff & (seed >> 40)),
291 (byte) (0xff & (seed >> 32)),
292 (byte) (0xff & (seed >> 24)),
293 (byte) (0xff & (seed >> 16)),
294 (byte) (0xff & (seed >> 8)),
295 (byte) (0xff & seed)
296 };
297 secureRandomSpi.engineSetSeed(tmp);
298 }
299 }
300
301 /**
302 Generates a user specified number of bytes. This function
303 is the basis for all the random functions.
304
305 @param bytes array to store generated bytes in
306 */
307 public void nextBytes(byte[] bytes)
308 {
309 randomBytesUsed += bytes.length;
310 counter++;
311 secureRandomSpi.engineNextBytes(bytes);
312 }
313
314 /**
315 Generates an integer containing the user specified
316 number of random bits. It is right justified and padded
317 with zeros.
318
319 @param numBits number of random bits to get, 0 <= numBits <= 32;
320
321 @return the random bits
322 */
323 protected final int next(int numBits)
324 {
325 if (numBits == 0)
326 return 0;
327
328 byte tmp[] = new byte[numBits / 8 + (1 * (numBits % 8))];
329
330 secureRandomSpi.engineNextBytes(tmp);
331 randomBytesUsed += tmp.length;
332 counter++;
333
334 int ret = 0;
335
336 for (int i = 0; i < tmp.length; i++)
337 ret |= tmp[i] << (8 * i);
338
339 return ret;
340 }
341
342 /**
343 Returns the given number of seed bytes. This method is
344 maintained only for backwards capability.
345
346 @param numBytes number of seed bytes to get
347
348 @return an array containing the seed bytes
349 */
350 public static byte[] getSeed(int numBytes)
351 {
352 byte tmp[] = new byte[numBytes];
353
354 new Random().nextBytes(tmp);
355 return tmp;
356 //return secureRandomSpi.engineGenerateSeed( numBytes );
357 }
358
359 /**
360 Returns the specified number of seed bytes.
361
362 @param numBytes number of seed bytes to get
363
364 @return an array containing the seed bytes
365 */
366 public byte[] generateSeed(int numBytes)
367 {
368 return secureRandomSpi.engineGenerateSeed(numBytes);
369 }
370
371}
Note: See TracBrowser for help on using the repository browser.