1. /*
  2. * @(#)SecureRandom.java 1.32 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.security;
  8. import java.util.Enumeration;
  9. /**
  10. * <p>This class provides a cryptographically strong pseudo-random number
  11. * generator (PRNG).
  12. *
  13. * <p>Like other algorithm-based classes in Java Security, SecureRandom
  14. * provides implementation-independent algorithms, whereby a caller
  15. * (application code) requests a particular PRNG algorithm
  16. * and is handed back a SecureRandom object for that algorithm. It is
  17. * also possible, if desired, to request a particular algorithm from a
  18. * particular provider. See the <code>getInstance</code> methods.
  19. *
  20. * <p>Thus, there are two ways to request a SecureRandom object: by
  21. * specifying either just an algorithm name, or both an algorithm name
  22. * and a package provider.
  23. *
  24. * <ul>
  25. *
  26. * <li>If just an algorithm name is specified, as in:
  27. * <pre>
  28. * SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
  29. * </pre>
  30. * the system will determine if there is an implementation of the algorithm
  31. * requested available in the environment, and if there is more than one, if
  32. * there is a preferred one.<p>
  33. *
  34. * <li>If both an algorithm name and a package provider are specified, as in:
  35. * <pre>
  36. * SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
  37. * </pre>
  38. * the system will determine if there is an implementation of the
  39. * algorithm in the package requested, and throw an exception if there
  40. * is not.
  41. *
  42. * </ul>
  43. *
  44. * <p>The SecureRandom implementation attempts to completely
  45. * randomize the internal state of the generator itself unless
  46. * the caller follows the call to a <code>getInstance</code> method
  47. * with a call to the <code>setSeed</code> method:
  48. * <pre>
  49. * SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
  50. * random.setSeed(seed);
  51. * </pre>
  52. *
  53. * <p>After the caller obtains the SecureRandom object from the
  54. * <code>getInstance</code> call, it can call <code>nextBytes</code>
  55. * to generate random bytes:
  56. * <pre>
  57. * byte bytes[] = new byte[20];
  58. * random.nextBytes(bytes);
  59. * </pre>
  60. *
  61. * <p>The caller may also invoke the <code>generateSeed</code> method
  62. * to generate a given number of seed bytes (to seed other random number
  63. * generators, for example):
  64. * <pre>
  65. * byte seed[] = random.generateSeed(20);
  66. * </pre>
  67. *
  68. * @see java.security.SecureRandomSpi
  69. * @see java.util.Random
  70. *
  71. * @version 1.32, 01/11/29
  72. * @author Benjamin Renaud
  73. * @author Josh Bloch
  74. */
  75. public class SecureRandom extends java.util.Random {
  76. /**
  77. * The provider.
  78. *
  79. * @serial
  80. * @since JDK 1.2
  81. */
  82. private Provider provider = null;
  83. /**
  84. * The provider implementation.
  85. *
  86. * @serial
  87. * @since JDK 1.2
  88. */
  89. private SecureRandomSpi secureRandomSpi = null;
  90. // Seed Generator
  91. private static SecureRandom seedGenerator = null;
  92. /**
  93. * <p>By using this constructor, the caller obtains a SecureRandom object
  94. * containing the implementation from the highest-priority installed
  95. * provider that has a SecureRandom implementation.
  96. *
  97. * <p>Note that this instance of SecureRandom has not been seeded.
  98. * A call to the <code>setSeed</code> method will seed the SecureRandom
  99. * object. If a call is not made to <code>setSeed</code>, the first call
  100. * to the <code>nextBytes</code> method will force the SecureRandom object
  101. * to seed itself.
  102. *
  103. * <p>This constructor is provided for backwards compatibility.
  104. * The caller is encouraged to use one of the alternative
  105. * <code>getInstance</code> methods to obtain a SecureRandom object.
  106. */
  107. public SecureRandom() {
  108. /*
  109. * This call to our superclass constructor will result in a call
  110. * to our own <code>setSeed</code> method, which will return
  111. * immediately when it is passed zero.
  112. */
  113. super(0);
  114. String prng = getPrngAlgorithm();
  115. if (prng == null) {
  116. // bummer, get the SUN implementation
  117. this.secureRandomSpi = new sun.security.provider.SecureRandom();
  118. this.provider = new sun.security.provider.Sun();
  119. } else {
  120. try {
  121. SecureRandom random = SecureRandom.getInstance(prng);
  122. this.secureRandomSpi = random.getSecureRandomSpi();
  123. this.provider = random.getProvider();
  124. } catch (NoSuchAlgorithmException nsae) {
  125. // never happens, because we made sure the algorithm exists
  126. }
  127. }
  128. }
  129. /**
  130. * <p>By using this constructor, the caller obtains a SecureRandom object
  131. * containing the implementation from the highest-priority installed
  132. * provider that has a SecureRandom implementation. This constructor
  133. * uses a user-provided seed in
  134. * preference to the self-seeding algorithm referred to in the empty
  135. * constructor description. It may be preferable to the empty constructor
  136. * if the caller has access to high-quality random bytes from some physical
  137. * device (for example, a radiation detector or a noisy diode).
  138. *
  139. * <p>This constructor is provided for backwards compatibility.
  140. * The caller is encouraged to use one of the alternative
  141. * <code>getInstance</code> methods to obtain a SecureRandom object, and
  142. * then to call the <code>setSeed</code> method to seed it.
  143. *
  144. * @param seed the seed.
  145. */
  146. public SecureRandom(byte seed[]) {
  147. super(0);
  148. String prng = getPrngAlgorithm();
  149. if (prng == null) {
  150. // bummer, get the SUN implementation
  151. this.secureRandomSpi = new sun.security.provider.SecureRandom();
  152. this.provider = new sun.security.provider.Sun();
  153. this.secureRandomSpi.engineSetSeed(seed);
  154. } else {
  155. try {
  156. SecureRandom random = getInstance(prng);
  157. this.secureRandomSpi = random.getSecureRandomSpi();
  158. this.provider = random.getProvider();
  159. this.secureRandomSpi.engineSetSeed(seed);
  160. } catch (NoSuchAlgorithmException nsae) {
  161. // never happens, because we made sure the algorithm exists
  162. }
  163. }
  164. }
  165. /**
  166. * Creates a SecureRandom object.
  167. *
  168. * @param secureRandomSpi the SecureRandom implementation.
  169. * @param provider the provider.
  170. */
  171. protected SecureRandom(SecureRandomSpi secureRandomSpi,
  172. Provider provider) {
  173. super(0);
  174. this.secureRandomSpi = secureRandomSpi;
  175. this.provider = provider;
  176. }
  177. /**
  178. * Generates a SecureRandom object that implements the specified
  179. * Pseudo Random Number Generator (PRNG) algorithm. If the default
  180. * provider package provides an implementation of the requested PRNG,
  181. * an instance of SecureRandom containing that implementation is returned.
  182. * If the PRNG is not available in the default
  183. * package, other packages are searched.
  184. *
  185. * <p>Note that the returned instance of SecureRandom has not been seeded.
  186. * A call to the <code>setSeed</code> method will seed the SecureRandom
  187. * object. If a call is not made to <code>setSeed</code>, the first call
  188. * to the <code>nextBytes</code> method will force the SecureRandom object
  189. * to seed itself.
  190. *
  191. * @param algorithm the name of the PRNG algorithm.
  192. * See Appendix A in the <a href=
  193. * "../../../guide/security/CryptoSpec.html#AppA">
  194. * Java Cryptography Architecture API Specification & Reference </a>
  195. * for information about standard PRNG algorithm names.
  196. *
  197. * @return the new SecureRandom object.
  198. *
  199. * @exception NoSuchAlgorithmException if the PRNG algorithm is
  200. * not available in the caller's environment.
  201. *
  202. * @since JDK1.2
  203. */
  204. public static SecureRandom getInstance(String algorithm)
  205. throws NoSuchAlgorithmException {
  206. try {
  207. Object[] objs = Security.getImpl(algorithm,
  208. "SecureRandom",
  209. null);
  210. return new SecureRandom((SecureRandomSpi)objs[0],
  211. (Provider)objs[1]);
  212. } catch(NoSuchProviderException e) {
  213. throw new NoSuchAlgorithmException(algorithm + " not found");
  214. }
  215. }
  216. /**
  217. * Generates a SecureRandom object for the specified PRNG
  218. * algorithm, as supplied from the specified provider, if such a
  219. * PRNG implementation is available from the provider.
  220. *
  221. * <p>Note that the returned instance of SecureRandom has not been seeded.
  222. * A call to the <code>setSeed</code> method will seed the SecureRandom
  223. * object. If a call is not made to <code>setSeed</code>, the first call
  224. * to the <code>nextBytes</code> method will force the SecureRandom object
  225. * to seed itself.
  226. *
  227. * @param algorithm the name of the PRNG algorithm.
  228. * See Appendix A in the <a href=
  229. * "../../../guide/security/CryptoSpec.html#AppA">
  230. * Java Cryptography Architecture API Specification & Reference </a>
  231. * for information about standard PRNG algorithm names.
  232. *
  233. * @param provider the name of the provider.
  234. *
  235. * @return the new SecureRandom object.
  236. *
  237. * @exception NoSuchAlgorithmException if the requested PRNG
  238. * implementation is not available from the provider.
  239. *
  240. * @exception NoSuchProviderException if the provider has not been
  241. * configured.
  242. *
  243. * @see Provider
  244. *
  245. * @since JDK1.2
  246. */
  247. public static SecureRandom getInstance(String algorithm, String provider)
  248. throws NoSuchAlgorithmException, NoSuchProviderException
  249. {
  250. if (provider == null || provider.length() == 0)
  251. throw new IllegalArgumentException("missing provider");
  252. Object[] objs = Security.getImpl(algorithm, "SecureRandom", provider);
  253. return new SecureRandom((SecureRandomSpi)objs[0], (Provider)objs[1]);
  254. }
  255. /**
  256. * Returns the SecureRandomSpi of this SecureRandom object.
  257. */
  258. SecureRandomSpi getSecureRandomSpi() {
  259. return secureRandomSpi;
  260. }
  261. /**
  262. * Returns the provider of this SecureRandom object.
  263. *
  264. * @return the provider of this SecureRandom object.
  265. */
  266. public final Provider getProvider() {
  267. return provider;
  268. }
  269. /**
  270. * Reseeds this random object. The given seed supplements, rather than
  271. * replaces, the existing seed. Thus, repeated calls are guaranteed
  272. * never to reduce randomness.
  273. *
  274. * @param seed the seed.
  275. */
  276. synchronized public void setSeed(byte[] seed) {
  277. secureRandomSpi.engineSetSeed(seed);
  278. }
  279. /**
  280. * Reseeds this random object, using the eight bytes contained
  281. * in the given <code>long seed</code>. The given seed supplements,
  282. * rather than replaces, the existing seed. Thus, repeated calls
  283. * are guaranteed never to reduce randomness.
  284. *
  285. * <p>This method is defined for compatibility with
  286. * <code>java.util.Random</code>.
  287. *
  288. * @param seed the seed.
  289. */
  290. public void setSeed(long seed) {
  291. /*
  292. * Ignore call from super constructor (as well as any other calls
  293. * unfortunate enough to be passing 0). It's critical that we
  294. * ignore call from superclass constructor, as digest has not
  295. * yet been initialized at that point.
  296. */
  297. if (seed != 0)
  298. secureRandomSpi.engineSetSeed(longToByteArray(seed));
  299. }
  300. /**
  301. * Generates a user-specified number of random bytes. This method is
  302. * used as the basis of all random entities returned by this class
  303. * (except seed bytes).
  304. *
  305. * @param bytes the array to be filled in with random bytes.
  306. */
  307. synchronized public void nextBytes(byte[] bytes) {
  308. secureRandomSpi.engineNextBytes(bytes);
  309. }
  310. /**
  311. * Generates an integer containing the user-specified number of
  312. * pseudo-random bits (right justified, with leading zeros). This
  313. * method overrides a <code>java.util.Random</code> method, and serves
  314. * to provide a source of random bits to all of the methods inherited
  315. * from that class (for example, <code>nextInt</code>,
  316. * <code>nextLong</code>, and <code>nextFloat</code>).
  317. *
  318. * @param numBits number of pseudo-random bits to be generated, where
  319. * 0 <= <code>numBits</code> <= 32.
  320. */
  321. final protected int next(int numBits) {
  322. int numBytes = (numBits+7)/8;
  323. byte b[] = new byte[numBytes];
  324. int next = 0;
  325. nextBytes(b);
  326. for (int i=0; i<numBytes; i++)
  327. next = (next << 8) + (b[i] & 0xFF);
  328. return next >>> (numBytes*8 - numBits);
  329. }
  330. /**
  331. * Returns the given number of seed bytes, computed using the seed
  332. * generation algorithm that this class uses to seed itself. This
  333. * call may be used to seed other random number generators.
  334. *
  335. * <p>This method is only included for backwards compatibility.
  336. * The caller is encouraged to use one of the alternative
  337. * <code>getInstance</code> methods to obtain a SecureRandom object, and
  338. * then call the <code>generateSeed</code> method to obtain seed bytes
  339. * from that object.
  340. *
  341. * @param numBytes the number of seed bytes to generate.
  342. *
  343. * @return the seed bytes.
  344. */
  345. public static byte[] getSeed(int numBytes) {
  346. if (seedGenerator == null)
  347. seedGenerator = new SecureRandom();
  348. return seedGenerator.generateSeed(numBytes);
  349. }
  350. /**
  351. * Returns the given number of seed bytes, computed using the seed
  352. * generation algorithm that this class uses to seed itself. This
  353. * call may be used to seed other random number generators.
  354. *
  355. * @param numBytes the number of seed bytes to generate.
  356. *
  357. * @return the seed bytes.
  358. */
  359. public byte[] generateSeed(int numBytes) {
  360. return secureRandomSpi.engineGenerateSeed(numBytes);
  361. }
  362. /**
  363. * Helper function to convert a long into a byte array (least significant
  364. * byte first).
  365. */
  366. private static byte[] longToByteArray(long l) {
  367. byte[] retVal = new byte[8];
  368. for (int i=0; i<8; i++) {
  369. retVal[i] = (byte) l;
  370. l >>= 8;
  371. }
  372. return retVal;
  373. }
  374. /**
  375. * Gets a default PRNG algorithm by looking through all registered
  376. * providers. Returns the first PRNG algorithm of the first provider that
  377. * has registered a SecureRandom implementation, or null if none of the
  378. * registered providers supplies a SecureRandom implementation.
  379. */
  380. private static String getPrngAlgorithm() {
  381. Provider[] provs = Security.getProviders();
  382. for (int i=0; i<provs.length; i++) {
  383. // search the provider's properties list for a property name
  384. // that starts with "SecureRandom."
  385. for (Enumeration e = provs[i].propertyNames();
  386. e.hasMoreElements();) {
  387. String propName = (String)e.nextElement();
  388. if (propName.startsWith("SecureRandom.")) {
  389. int index = propName.indexOf(".", 0);
  390. return propName.substring(index+1);
  391. }
  392. }
  393. }
  394. return null;
  395. }
  396. // Declare serialVersionUID to be compatible with JDK1.1
  397. static final long serialVersionUID = 4940670005562187L;
  398. // Retain unused values serialized from JDK1.1
  399. /**
  400. * @serial
  401. */
  402. private byte[] state;
  403. /**
  404. * @serial
  405. */
  406. private MessageDigest digest = null;
  407. /**
  408. * @serial
  409. *
  410. * We know that the MessageDigest class does not implement
  411. * java.io.Serializable. However, since this field is no longer
  412. * used, it will always be NULL and won't affect the serialization
  413. * of the SecureRandom class itself.
  414. */
  415. private byte[] randomBytes;
  416. /**
  417. * @serial
  418. */
  419. private int randomBytesUsed;
  420. /**
  421. * @serial
  422. */
  423. private long counter;
  424. }