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