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