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