1 /* 2 * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.security; 27 28 import java.math.BigInteger; 29 import java.util.*; 30 import java.util.random.RandomGenerator; 31 import java.util.regex.*; 32 import java.security.Provider.Service; 33 import java.util.function.Function; 34 35 import dalvik.system.VMRuntime; 36 import jdk.internal.util.random.RandomSupport.RandomGeneratorProperties; 37 import sun.security.jca.*; 38 import sun.security.jca.GetInstance.Instance; 39 import sun.security.util.Debug; 40 41 /** 42 * This class provides a cryptographically strong random number 43 * generator (RNG). 44 * 45 * <p>A cryptographically strong random number minimally complies with the 46 * statistical random number generator tests specified in 47 * <a href="http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.140-2.pdf"> 48 * <i>FIPS 140-2, Security Requirements for Cryptographic Modules</i></a>, 49 * section 4.9.1. 50 * Additionally, {@code SecureRandom} must produce non-deterministic output. 51 * Therefore any seed material passed to a {@code SecureRandom} object must be 52 * unpredictable, and all {@code SecureRandom} output sequences must be 53 * cryptographically strong, as described in 54 * <a href="http://tools.ietf.org/html/rfc4086"> 55 * <i>RFC 4086: Randomness Requirements for Security</i></a>. 56 * 57 * <p> Many {@code SecureRandom} implementations are in the form of a 58 * pseudo-random number generator (PRNG, also known as deterministic random 59 * bits generator or DRBG), which means they use a deterministic algorithm 60 * to produce a pseudo-random sequence from a random seed. 61 * Other implementations may produce true random numbers, 62 * and yet others may use a combination of both techniques. 63 * 64 * <p>A caller obtains a {@code SecureRandom} instance via the 65 * no-argument constructor or one of the {@code getInstance} methods. 66 * For example: 67 * 68 * <blockquote><pre> 69 * SecureRandom r1 = new SecureRandom(); 70 * SecureRandom r2 = SecureRandom.getInstance("NativePRNG"); 71 * SecureRandom r3 = SecureRandom.getInstance("DRBG", 72 * DrbgParameters.instantiation(128, RESEED_ONLY, null));</pre> 73 * </blockquote> 74 * 75 * <p> The third statement above returns a {@code SecureRandom} object of the 76 * specific algorithm supporting the specific instantiate parameters. The 77 * implementation's effective instantiated parameters must match this minimum 78 * request but is not necessarily the same. For example, even if the request 79 * does not require a certain feature, the actual instantiation can provide 80 * the feature. An implementation may lazily instantiate a {@code SecureRandom} 81 * until it's actually used, but the effective instantiate parameters must be 82 * determined right after it's created and {@link #getParameters()} should 83 * always return the same result unchanged. 84 * 85 * <p> Typical callers of {@code SecureRandom} invoke the following methods 86 * to retrieve random bytes: 87 * 88 * <blockquote><pre> 89 * SecureRandom random = new SecureRandom(); 90 * byte[] bytes = new byte[20]; 91 * random.nextBytes(bytes);</pre> 92 * </blockquote> 93 * 94 * <p> Callers may also invoke the {@link #generateSeed} method 95 * to generate a given number of seed bytes (to seed other random number 96 * generators, for example): 97 * 98 * <blockquote><pre> 99 * byte[] seed = random.generateSeed(20);</pre> 100 * </blockquote> 101 * 102 * <p> A newly created PRNG {@code SecureRandom} object is not seeded (except 103 * if it is created by {@link #SecureRandom(byte[])}). The first call to 104 * {@code nextBytes} will force it to seed itself from an implementation- 105 * specific entropy source. This self-seeding will not occur if {@code setSeed} 106 * was previously called. 107 * 108 * <p> A {@code SecureRandom} can be reseeded at any time by calling the 109 * {@code reseed} or {@code setSeed} method. The {@code reseed} method 110 * reads entropy input from its entropy source to reseed itself. 111 * The {@code setSeed} method requires the caller to provide the seed. 112 * 113 * <p> Please note that {@code reseed} may not be supported by all 114 * {@code SecureRandom} implementations. 115 * 116 * <p> Some {@code SecureRandom} implementations may accept a 117 * {@link SecureRandomParameters} parameter in its 118 * {@link #nextBytes(byte[], SecureRandomParameters)} and 119 * {@link #reseed(SecureRandomParameters)} methods to further 120 * control the behavior of the methods. 121 * 122 * <p> Note: Depending on the implementation, the {@code generateSeed}, 123 * {@code reseed} and {@code nextBytes} methods may block as entropy is being 124 * gathered, for example, if the entropy source is /dev/random on various 125 * Unix-like operating systems. 126 * 127 * <h2> Thread safety </h2> 128 * {@code SecureRandom} objects are safe for use by multiple concurrent threads. 129 * 130 * @implSpec 131 * A {@code SecureRandom} service provider can advertise that it is thread-safe 132 * by setting the <a href= 133 * "{@docRoot}/../specs/security/standard-names.html#service-attributes">service 134 * provider attribute</a> "ThreadSafe" to "true" when registering the provider. 135 * Otherwise, this class will instead synchronize access to the following 136 * methods of the {@code SecureRandomSpi} implementation: 137 * <ul> 138 * <li>{@link SecureRandomSpi#engineSetSeed(byte[])} 139 * <li>{@link SecureRandomSpi#engineNextBytes(byte[])} 140 * <li>{@link SecureRandomSpi#engineNextBytes(byte[], SecureRandomParameters)} 141 * <li>{@link SecureRandomSpi#engineGenerateSeed(int)} 142 * <li>{@link SecureRandomSpi#engineReseed(SecureRandomParameters)} 143 * </ul> 144 * 145 * The SHA1PRNG algorithm from the Crypto provider has been deprecated as it was insecure, and also 146 * incorrectly used by some apps as a key derivation function. See 147 * <a href="http://android-developers.blogspot.com/2016/06/security-crypto-provider-deprecated-in.html"> 148 * Security "Crypto" provider deprecated in Android N</a> for details. 149 * 150 * @see java.security.SecureRandomSpi 151 * @see java.util.Random 152 * 153 * @author Benjamin Renaud 154 * @author Josh Bloch 155 * @since 1.1 156 */ 157 158 @RandomGeneratorProperties( 159 name = "SecureRandom", 160 isStochastic = true 161 ) 162 public class SecureRandom extends java.util.Random { 163 164 // Android-removed: this debugging mechanism is not used in Android. 165 /* 166 private static final Debug pdebug = 167 Debug.getInstance("provider", "Provider"); 168 private static final boolean skipDebug = 169 Debug.isOn("engine=") && !Debug.isOn("securerandom"); 170 */ 171 // END Android-removed 172 173 /** 174 * The provider. 175 * 176 * @serial 177 * @since 1.2 178 */ 179 private Provider provider = null; 180 181 /** 182 * The provider implementation. 183 * 184 * @serial 185 * @since 1.2 186 */ 187 private SecureRandomSpi secureRandomSpi = null; 188 189 /** 190 * Thread safety. 191 * 192 * @serial 193 * @since 9 194 */ 195 private final boolean threadSafe; 196 197 /** 198 * The algorithm name or {@code null} if unknown. 199 * 200 * @serial 201 * @since 1.5 202 */ 203 private String algorithm; 204 205 // Seed Generator 206 private static volatile SecureRandom seedGenerator; 207 208 /** 209 * Constructs a secure random number generator (RNG) implementing the 210 * default random number algorithm. 211 * 212 * <p> This constructor traverses the list of registered security Providers, 213 * starting with the most preferred Provider. 214 * A new {@code SecureRandom} object encapsulating the 215 * {@code SecureRandomSpi} implementation from the first 216 * Provider that supports a {@code SecureRandom} (RNG) algorithm is returned. 217 * If none of the Providers support a RNG algorithm, 218 * then an implementation-specific default is returned. 219 * 220 * <p> Note that the list of registered providers may be retrieved via 221 * the {@link Security#getProviders() Security.getProviders()} method. 222 * 223 * <p> See the {@code SecureRandom} section in the <a href= 224 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms"> 225 * Java Security Standard Algorithm Names Specification</a> 226 * for information about standard RNG algorithm names. 227 */ SecureRandom()228 public SecureRandom() { 229 /* 230 * This call to our superclass constructor will result in a call 231 * to our own {@code setSeed} method, which will return 232 * immediately when it is passed zero. 233 */ 234 super(0); 235 getDefaultPRNG(false, null); 236 this.threadSafe = getThreadSafe(); 237 } 238 getThreadSafe()239 private boolean getThreadSafe() { 240 if (provider == null || algorithm == null) { 241 return false; 242 } else { 243 return Boolean.parseBoolean(provider.getProperty( 244 "SecureRandom." + algorithm + " ThreadSafe", "false")); 245 } 246 } 247 248 /** 249 * Constructs a secure random number generator (RNG) implementing the 250 * default random number algorithm. 251 * The {@code SecureRandom} instance is seeded with the specified seed bytes. 252 * 253 * <p> This constructor traverses the list of registered security Providers, 254 * starting with the most preferred Provider. 255 * A new {@code SecureRandom} object encapsulating the 256 * {@code SecureRandomSpi} implementation from the first 257 * Provider that supports a {@code SecureRandom} (RNG) algorithm is returned. 258 * If none of the Providers support a RNG algorithm, 259 * then an implementation-specific default is returned. 260 * 261 * <p> Note that the list of registered providers may be retrieved via 262 * the {@link Security#getProviders() Security.getProviders()} method. 263 * 264 * <p> See the {@code SecureRandom} section in the <a href= 265 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms"> 266 * Java Security Standard Algorithm Names Specification</a> 267 * for information about standard RNG algorithm names. 268 * 269 * @param seed the seed. 270 */ SecureRandom(byte[] seed)271 public SecureRandom(byte[] seed) { 272 super(0); 273 getDefaultPRNG(true, seed); 274 this.threadSafe = getThreadSafe(); 275 } 276 getDefaultPRNG(boolean setSeed, byte[] seed)277 private void getDefaultPRNG(boolean setSeed, byte[] seed) { 278 // Android-changed: Search for algorithm here until the Provider class caches the algo list. 279 /* 280 Service prngService = null; 281 String prngAlgorithm = null; 282 for (Provider p : Providers.getProviderList().providers()) { 283 // SUN provider uses the SunEntries.DEF_SECURE_RANDOM_ALGO 284 // as the default SecureRandom algorithm; for other providers, 285 // Provider.getDefaultSecureRandom() will use the 1st 286 // registered SecureRandom algorithm 287 if (p.getName().equals("SUN")) { 288 prngAlgorithm = SunEntries.DEF_SECURE_RANDOM_ALGO; 289 prngService = p.getService("SecureRandom", prngAlgorithm); 290 break; 291 } else { 292 prngService = p.getDefaultSecureRandomService(); 293 if (prngService != null) { 294 prngAlgorithm = prngService.getAlgorithm(); 295 break; 296 } 297 } 298 } 299 // per javadoc, if none of the Providers support a RNG algorithm, 300 // then an implementation-specific default is returned. 301 if (prngService == null) { 302 prngAlgorithm = "SHA1PRNG"; 303 this.secureRandomSpi = new sun.security.provider.SecureRandom(); 304 this.provider = Providers.getSunProvider(); 305 } else { 306 try { 307 this.secureRandomSpi = (SecureRandomSpi) 308 prngService.newInstance(null); 309 this.provider = prngService.getProvider(); 310 } catch (NoSuchAlgorithmException nsae) { 311 // should not happen 312 throw new RuntimeException(nsae); 313 } 314 } 315 if (setSeed) { 316 this.secureRandomSpi.engineSetSeed(seed); 317 } 318 // JDK 1.1 based implementations subclass SecureRandom instead of 319 // SecureRandomSpi. They will also go through this code path because 320 // they must call a SecureRandom constructor as it is their superclass. 321 // If we are dealing with such an implementation, do not set the 322 // algorithm value as it would be inaccurate. 323 if (getClass() == SecureRandom.class) { 324 this.algorithm = prngAlgorithm; 325 } 326 */ 327 String prng = getPrngAlgorithm(); 328 if (prng == null) { 329 // Android-changed: This should never happen, we always provide a SecureRandom 330 throw new IllegalStateException("No SecureRandom implementation!"); 331 } else { 332 try { 333 SecureRandom random = SecureRandom.getInstance(prng); 334 this.secureRandomSpi = random.secureRandomSpi; 335 this.provider = random.getProvider(); 336 if (setSeed) { 337 this.secureRandomSpi.engineSetSeed(seed); 338 } 339 } catch (NoSuchAlgorithmException nsae) { 340 // never happens, because we made sure the algorithm exists 341 throw new RuntimeException(nsae); 342 } 343 } 344 // JDK 1.1 based implementations subclass SecureRandom instead of 345 // SecureRandomSpi. They will also go through this code path because 346 // they must call a SecureRandom constructor as it is their superclass. 347 // If we are dealing with such an implementation, do not set the 348 // algorithm value as it would be inaccurate. 349 if (getClass() == SecureRandom.class) { 350 this.algorithm = prng; 351 } 352 } 353 354 // Android-added: Used by getDefaultPRNG. 355 /** 356 * Gets a default PRNG algorithm by looking through all registered 357 * providers. Returns the first PRNG algorithm of the first provider that 358 * has registered a SecureRandom implementation, or null if none of the 359 * registered providers supplies a SecureRandom implementation. 360 */ getPrngAlgorithm()361 private static String getPrngAlgorithm() { 362 for (Provider p : Providers.getProviderList().providers()) { 363 for (Service s : p.getServices()) { 364 if (s.getType().equals("SecureRandom")) { 365 return s.getAlgorithm(); 366 } 367 } 368 } 369 return null; 370 } 371 372 /** 373 * Creates a {@code SecureRandom} object. 374 * 375 * @param secureRandomSpi the {@code SecureRandom} implementation. 376 * @param provider the provider. 377 */ SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider)378 protected SecureRandom(SecureRandomSpi secureRandomSpi, 379 Provider provider) { 380 this(secureRandomSpi, provider, null); 381 } 382 SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider, String algorithm)383 private SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider, 384 String algorithm) { 385 super(0); 386 this.secureRandomSpi = secureRandomSpi; 387 this.provider = provider; 388 this.algorithm = algorithm; 389 this.threadSafe = getThreadSafe(); 390 391 // BEGIN Android-removed: this debugging mechanism is not supported in Android. 392 /* 393 if (!skipDebug && pdebug != null) { 394 pdebug.println("SecureRandom." + algorithm + 395 " algorithm from: " + getProviderName()); 396 } 397 */ 398 // END Android-removed: this debugging mechanism is not supported in Android. 399 } 400 getProviderName()401 private String getProviderName() { 402 return (provider == null) ? "(no provider)" : provider.getName(); 403 } 404 405 /** 406 * Returns a {@code SecureRandom} object that implements the specified 407 * Random Number Generator (RNG) algorithm. 408 * 409 * <p> This method traverses the list of registered security Providers, 410 * starting with the most preferred Provider. 411 * A new {@code SecureRandom} object encapsulating the 412 * {@code SecureRandomSpi} implementation from the first 413 * Provider that supports the specified algorithm is returned. 414 * 415 * <p> Note that the list of registered providers may be retrieved via 416 * the {@link Security#getProviders() Security.getProviders()} method. 417 * 418 * @implNote 419 * The JDK Reference Implementation additionally uses the 420 * {@code jdk.security.provider.preferred} 421 * {@link Security#getProperty(String) Security} property to determine 422 * the preferred provider order for the specified algorithm. This 423 * may be different than the order of providers returned by 424 * {@link Security#getProviders() Security.getProviders()}. 425 * 426 * @param algorithm the name of the RNG algorithm. 427 * See the {@code SecureRandom} section in the <a href= 428 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms"> 429 * Java Security Standard Algorithm Names Specification</a> 430 * for information about standard RNG algorithm names. 431 * 432 * @return the new {@code SecureRandom} object 433 * 434 * @throws NoSuchAlgorithmException if no {@code Provider} supports a 435 * {@code SecureRandomSpi} implementation for the 436 * specified algorithm 437 * 438 * @throws NullPointerException if {@code algorithm} is {@code null} 439 * 440 * @see Provider 441 * 442 * @since 1.2 443 */ getInstance(String algorithm)444 public static SecureRandom getInstance(String algorithm) 445 throws NoSuchAlgorithmException { 446 Objects.requireNonNull(algorithm, "null algorithm name"); 447 Instance instance = GetInstance.getInstance("SecureRandom", 448 SecureRandomSpi.class, algorithm); 449 return new SecureRandom((SecureRandomSpi)instance.impl, 450 instance.provider, algorithm); 451 } 452 453 /** 454 * Returns a {@code SecureRandom} object that implements the specified 455 * Random Number Generator (RNG) algorithm. 456 * 457 * <p> A new {@code SecureRandom} object encapsulating the 458 * {@code SecureRandomSpi} implementation from the specified provider 459 * is returned. The specified provider must be registered 460 * in the security provider list. 461 * 462 * <p> Note that the list of registered providers may be retrieved via 463 * the {@link Security#getProviders() Security.getProviders()} method. 464 * 465 * @param algorithm the name of the RNG algorithm. 466 * See the {@code SecureRandom} section in the <a href= 467 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms"> 468 * Java Security Standard Algorithm Names Specification</a> 469 * for information about standard RNG algorithm names. 470 * 471 * @param provider the name of the provider. 472 * 473 * @return the new {@code SecureRandom} object 474 * 475 * @throws IllegalArgumentException if the provider name is {@code null} 476 * or empty 477 * 478 * @throws NoSuchAlgorithmException if a {@code SecureRandomSpi} 479 * implementation for the specified algorithm is not 480 * available from the specified provider 481 * 482 * @throws NoSuchProviderException if the specified provider is not 483 * registered in the security provider list 484 * 485 * @throws NullPointerException if {@code algorithm} is {@code null} 486 * 487 * @see Provider 488 * 489 * @since 1.2 490 */ getInstance(String algorithm, String provider)491 public static SecureRandom getInstance(String algorithm, String provider) 492 throws NoSuchAlgorithmException, NoSuchProviderException { 493 Objects.requireNonNull(algorithm, "null algorithm name"); 494 Instance instance = GetInstance.getInstance("SecureRandom", 495 SecureRandomSpi.class, algorithm, provider); 496 return new SecureRandom((SecureRandomSpi)instance.impl, 497 instance.provider, algorithm); 498 } 499 500 /** 501 * Returns a {@code SecureRandom} object that implements the specified 502 * Random Number Generator (RNG) algorithm. 503 * 504 * <p> A new {@code SecureRandom} object encapsulating the 505 * {@code SecureRandomSpi} implementation from the specified {@code Provider} 506 * object is returned. Note that the specified {@code Provider} object 507 * does not have to be registered in the provider list. 508 * 509 * @param algorithm the name of the RNG algorithm. 510 * See the {@code SecureRandom} section in the <a href= 511 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms"> 512 * Java Security Standard Algorithm Names Specification</a> 513 * for information about standard RNG algorithm names. 514 * 515 * @param provider the provider. 516 * 517 * @return the new {@code SecureRandom} object 518 * 519 * @throws IllegalArgumentException if the specified provider is 520 * {@code null} 521 * 522 * @throws NoSuchAlgorithmException if a {@code SecureRandomSpi} 523 * implementation for the specified algorithm is not available 524 * from the specified {@code Provider} object 525 * 526 * @throws NullPointerException if {@code algorithm} is {@code null} 527 * 528 * @see Provider 529 * 530 * @since 1.4 531 */ getInstance(String algorithm, Provider provider)532 public static SecureRandom getInstance(String algorithm, 533 Provider provider) throws NoSuchAlgorithmException { 534 Objects.requireNonNull(algorithm, "null algorithm name"); 535 Instance instance = GetInstance.getInstance("SecureRandom", 536 SecureRandomSpi.class, algorithm, provider); 537 return new SecureRandom((SecureRandomSpi)instance.impl, 538 instance.provider, algorithm); 539 } 540 541 /** 542 * Returns a {@code SecureRandom} object that implements the specified 543 * Random Number Generator (RNG) algorithm and supports the specified 544 * {@code SecureRandomParameters} request. 545 * 546 * <p> This method traverses the list of registered security Providers, 547 * starting with the most preferred Provider. 548 * A new {@code SecureRandom} object encapsulating the 549 * {@code SecureRandomSpi} implementation from the first 550 * Provider that supports the specified algorithm and the specified 551 * {@code SecureRandomParameters} is returned. 552 * 553 * <p> Note that the list of registered providers may be retrieved via 554 * the {@link Security#getProviders() Security.getProviders()} method. 555 * 556 * @implNote 557 * The JDK Reference Implementation additionally uses the 558 * {@code jdk.security.provider.preferred} property to determine 559 * the preferred provider order for the specified algorithm. This 560 * may be different than the order of providers returned by 561 * {@link Security#getProviders() Security.getProviders()}. 562 * 563 * @param algorithm the name of the RNG algorithm. 564 * See the {@code SecureRandom} section in the <a href= 565 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms"> 566 * Java Security Standard Algorithm Names Specification</a> 567 * for information about standard RNG algorithm names. 568 * 569 * @param params the {@code SecureRandomParameters} 570 * the newly created {@code SecureRandom} object must support. 571 * 572 * @return the new {@code SecureRandom} object 573 * 574 * @throws IllegalArgumentException if the specified params is 575 * {@code null} 576 * 577 * @throws NoSuchAlgorithmException if no Provider supports a 578 * {@code SecureRandomSpi} implementation for the specified 579 * algorithm and parameters 580 * 581 * @throws NullPointerException if {@code algorithm} is {@code null} 582 * 583 * @see Provider 584 * 585 * @since 9 586 */ getInstance( String algorithm, SecureRandomParameters params)587 public static SecureRandom getInstance( 588 String algorithm, SecureRandomParameters params) 589 throws NoSuchAlgorithmException { 590 Objects.requireNonNull(algorithm, "null algorithm name"); 591 if (params == null) { 592 throw new IllegalArgumentException("params cannot be null"); 593 } 594 Instance instance = GetInstance.getInstance("SecureRandom", 595 SecureRandomSpi.class, algorithm, params); 596 return new SecureRandom((SecureRandomSpi)instance.impl, 597 instance.provider, algorithm); 598 } 599 600 /** 601 * Returns a {@code SecureRandom} object that implements the specified 602 * Random Number Generator (RNG) algorithm and supports the specified 603 * {@code SecureRandomParameters} request. 604 * 605 * <p> A new {@code SecureRandom} object encapsulating the 606 * {@code SecureRandomSpi} implementation from the specified provider 607 * is returned. The specified provider must be registered 608 * in the security provider list. 609 * 610 * <p> Note that the list of registered providers may be retrieved via 611 * the {@link Security#getProviders() Security.getProviders()} method. 612 * 613 * @param algorithm the name of the RNG algorithm. 614 * See the {@code SecureRandom} section in the <a href= 615 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms"> 616 * Java Security Standard Algorithm Names Specification</a> 617 * for information about standard RNG algorithm names. 618 * 619 * @param params the {@code SecureRandomParameters} 620 * the newly created {@code SecureRandom} object must support. 621 * 622 * @param provider the name of the provider. 623 * 624 * @return the new {@code SecureRandom} object 625 * 626 * @throws IllegalArgumentException if the provider name is {@code null} 627 * or empty, or params is {@code null} 628 * 629 * @throws NoSuchAlgorithmException if the specified provider does not 630 * support a {@code SecureRandomSpi} implementation for the 631 * specified algorithm and parameters 632 * 633 * @throws NoSuchProviderException if the specified provider is not 634 * registered in the security provider list 635 * 636 * @throws NullPointerException if {@code algorithm} is {@code null} 637 * 638 * @see Provider 639 * 640 * @since 9 641 */ getInstance(String algorithm, SecureRandomParameters params, String provider)642 public static SecureRandom getInstance(String algorithm, 643 SecureRandomParameters params, String provider) 644 throws NoSuchAlgorithmException, NoSuchProviderException { 645 Objects.requireNonNull(algorithm, "null algorithm name"); 646 if (params == null) { 647 throw new IllegalArgumentException("params cannot be null"); 648 } 649 Instance instance = GetInstance.getInstance("SecureRandom", 650 SecureRandomSpi.class, algorithm, params, provider); 651 return new SecureRandom((SecureRandomSpi)instance.impl, 652 instance.provider, algorithm); 653 } 654 655 /** 656 * Returns a {@code SecureRandom} object that implements the specified 657 * Random Number Generator (RNG) algorithm and supports the specified 658 * {@code SecureRandomParameters} request. 659 * 660 * <p> A new {@code SecureRandom} object encapsulating the 661 * {@code SecureRandomSpi} implementation from the specified 662 * {@code Provider} object is returned. Note that the specified 663 * {@code Provider} object does not have to be registered in the 664 * provider list. 665 * 666 * @param algorithm the name of the RNG algorithm. 667 * See the {@code SecureRandom} section in the <a href= 668 * "{@docRoot}/../specs/security/standard-names.html#securerandom-number-generation-algorithms"> 669 * Java Security Standard Algorithm Names Specification</a> 670 * for information about standard RNG algorithm names. 671 * 672 * @param params the {@code SecureRandomParameters} 673 * the newly created {@code SecureRandom} object must support. 674 * 675 * @param provider the provider. 676 * 677 * @return the new {@code SecureRandom} object 678 * 679 * @throws IllegalArgumentException if the specified provider or params 680 * is {@code null} 681 * 682 * @throws NoSuchAlgorithmException if the specified provider does not 683 * support a {@code SecureRandomSpi} implementation for the 684 * specified algorithm and parameters 685 * 686 * @throws NullPointerException if {@code algorithm} is {@code null} 687 * 688 * @see Provider 689 * 690 * @since 9 691 */ getInstance(String algorithm, SecureRandomParameters params, Provider provider)692 public static SecureRandom getInstance(String algorithm, 693 SecureRandomParameters params, Provider provider) 694 throws NoSuchAlgorithmException { 695 Objects.requireNonNull(algorithm, "null algorithm name"); 696 if (params == null) { 697 throw new IllegalArgumentException("params cannot be null"); 698 } 699 Instance instance = GetInstance.getInstance("SecureRandom", 700 SecureRandomSpi.class, algorithm, params, provider); 701 return new SecureRandom((SecureRandomSpi)instance.impl, 702 instance.provider, algorithm); 703 } 704 705 /** 706 * Returns the provider of this {@code SecureRandom} object. 707 * 708 * @return the provider of this {@code SecureRandom} object. 709 */ getProvider()710 public final Provider getProvider() { 711 return provider; 712 } 713 714 /** 715 * Returns the name of the algorithm implemented by this 716 * {@code SecureRandom} object. 717 * 718 * @return the name of the algorithm or {@code unknown} 719 * if the algorithm name cannot be determined. 720 * @since 1.5 721 */ getAlgorithm()722 public String getAlgorithm() { 723 return Objects.toString(algorithm, "unknown"); 724 } 725 726 /** 727 * Returns a Human-readable string representation of this 728 * {@code SecureRandom}. 729 * 730 * @return the string representation 731 */ 732 @Override toString()733 public String toString() { 734 return secureRandomSpi.toString(); 735 } 736 737 /** 738 * Returns the effective {@link SecureRandomParameters} for this 739 * {@code SecureRandom} instance. 740 * <p> 741 * The returned value can be different from the 742 * {@code SecureRandomParameters} object passed into a {@code getInstance} 743 * method, but it cannot change during the lifetime of this 744 * {@code SecureRandom} object. 745 * <p> 746 * A caller can use the returned value to find out what features this 747 * {@code SecureRandom} supports. 748 * 749 * @return the effective {@link SecureRandomParameters} parameters, 750 * or {@code null} if no parameters were used. 751 * 752 * @since 9 753 * @see SecureRandomSpi 754 */ getParameters()755 public SecureRandomParameters getParameters() { 756 return secureRandomSpi.engineGetParameters(); 757 } 758 759 /** 760 * Reseeds this random object with the given seed. The seed supplements, 761 * rather than replaces, the existing seed. Thus, repeated calls are 762 * guaranteed never to reduce randomness. 763 * <p> 764 * A PRNG {@code SecureRandom} will not seed itself automatically if 765 * {@code setSeed} is called before any {@code nextBytes} or {@code reseed} 766 * calls. The caller should make sure that the {@code seed} argument 767 * contains enough entropy for the security of this {@code SecureRandom}. 768 * 769 * @param seed the seed. 770 * 771 * @see #getSeed 772 */ setSeed(byte[] seed)773 public void setSeed(byte[] seed) { 774 if (threadSafe) { 775 secureRandomSpi.engineSetSeed(seed); 776 } else { 777 synchronized (this) { 778 secureRandomSpi.engineSetSeed(seed); 779 } 780 } 781 } 782 783 /** 784 * Reseeds this random object, using the eight bytes contained 785 * in the given {@code long seed}. The given seed supplements, 786 * rather than replaces, the existing seed. Thus, repeated calls 787 * are guaranteed never to reduce randomness. 788 * 789 * <p>This method is defined for compatibility with 790 * {@code java.util.Random}. 791 * 792 * @param seed the seed. 793 * 794 * @see #getSeed 795 */ 796 @Override setSeed(long seed)797 public void setSeed(long seed) { 798 /* 799 * Ignore call from super constructor as well as any other calls 800 * unfortunate enough to be passing 0. All SecureRandom 801 * constructors call `super(0)` which leads to `setSeed(0)`. 802 * We either keep the object unseeded (in `new SecureRandom()`) 803 * or we seed the object explicitly (in `new SecureRandom(byte[])`). 804 */ 805 if (seed != 0) { 806 setSeed(longToByteArray(seed)); 807 } 808 } 809 810 /** 811 * Generates a user-specified number of random bytes. 812 * 813 * @param bytes the array to be filled in with random bytes. 814 */ 815 @Override nextBytes(byte[] bytes)816 public void nextBytes(byte[] bytes) { 817 if (threadSafe) { 818 secureRandomSpi.engineNextBytes(bytes); 819 } else { 820 synchronized (this) { 821 secureRandomSpi.engineNextBytes(bytes); 822 } 823 } 824 } 825 826 /** 827 * Generates a user-specified number of random bytes with 828 * additional parameters. 829 * 830 * @param bytes the array to be filled in with random bytes 831 * @param params additional parameters 832 * @throws NullPointerException if {@code bytes} is null 833 * @throws UnsupportedOperationException if the underlying provider 834 * implementation has not overridden this method 835 * @throws IllegalArgumentException if {@code params} is {@code null}, 836 * illegal or unsupported by this {@code SecureRandom} 837 * 838 * @since 9 839 */ nextBytes(byte[] bytes, SecureRandomParameters params)840 public void nextBytes(byte[] bytes, SecureRandomParameters params) { 841 if (params == null) { 842 throw new IllegalArgumentException("params cannot be null"); 843 } 844 if (threadSafe) { 845 secureRandomSpi.engineNextBytes( 846 Objects.requireNonNull(bytes), params); 847 } else { 848 synchronized (this) { 849 secureRandomSpi.engineNextBytes( 850 Objects.requireNonNull(bytes), params); 851 } 852 } 853 } 854 855 /** 856 * Generates an integer containing the user-specified number of 857 * pseudo-random bits (right justified, with leading zeros). This 858 * method overrides a {@code java.util.Random} method, and serves 859 * to provide a source of random bits to all of the methods inherited 860 * from that class (for example, {@code nextInt}, 861 * {@code nextLong}, and {@code nextFloat}). 862 * 863 * @param numBits number of pseudo-random bits to be generated, where 864 * {@code 0 <= numBits <= 32}. 865 * 866 * @return an {@code int} containing the user-specified number 867 * of pseudo-random bits (right justified, with leading zeros). 868 */ 869 @Override next(int numBits)870 protected final int next(int numBits) { 871 int numBytes = (numBits+7)/8; 872 byte[] b = new byte[numBytes]; 873 int next = 0; 874 875 nextBytes(b); 876 for (int i = 0; i < numBytes; i++) { 877 next = (next << 8) + (b[i] & 0xFF); 878 } 879 880 return next >>> (numBytes*8 - numBits); 881 } 882 883 /** 884 * Returns the given number of seed bytes, computed using the seed 885 * generation algorithm that this class uses to seed itself. This 886 * call may be used to seed other random number generators. 887 * 888 * <p>This method is only included for backwards compatibility. 889 * The caller is encouraged to use one of the alternative 890 * {@code getInstance} methods to obtain a {@code SecureRandom} object, and 891 * then call the {@code generateSeed} method to obtain seed bytes 892 * from that object. 893 * 894 * @param numBytes the number of seed bytes to generate. 895 * 896 * @throws IllegalArgumentException if {@code numBytes} is negative 897 * @return the seed bytes. 898 * 899 * @see #setSeed 900 */ getSeed(int numBytes)901 public static byte[] getSeed(int numBytes) { 902 SecureRandom seedGen = seedGenerator; 903 if (seedGen == null) { 904 seedGen = new SecureRandom(); 905 seedGenerator = seedGen; 906 } 907 return seedGen.generateSeed(numBytes); 908 } 909 910 /** 911 * Returns the given number of seed bytes, computed using the seed 912 * generation algorithm that this class uses to seed itself. This 913 * call may be used to seed other random number generators. 914 * 915 * @param numBytes the number of seed bytes to generate. 916 * @throws IllegalArgumentException if {@code numBytes} is negative 917 * @return the seed bytes. 918 */ generateSeed(int numBytes)919 public byte[] generateSeed(int numBytes) { 920 if (numBytes < 0) { 921 throw new IllegalArgumentException("numBytes cannot be negative"); 922 } 923 if (threadSafe) { 924 return secureRandomSpi.engineGenerateSeed(numBytes); 925 } else { 926 synchronized (this) { 927 return secureRandomSpi.engineGenerateSeed(numBytes); 928 } 929 } 930 } 931 932 /** 933 * Helper function to convert a long into a byte array (least significant 934 * byte first). 935 */ longToByteArray(long l)936 private static byte[] longToByteArray(long l) { 937 byte[] retVal = new byte[8]; 938 939 for (int i = 0; i < 8; i++) { 940 retVal[i] = (byte) l; 941 l >>= 8; 942 } 943 944 return retVal; 945 } 946 947 /* 948 * Lazily initialize since Pattern.compile() is heavy. 949 * Effective Java (2nd Edition), Item 71. 950 */ 951 private static final class StrongPatternHolder { 952 /* 953 * Entries are alg:prov separated by , 954 * Allow for prepended/appended whitespace between entries. 955 * 956 * Capture groups: 957 * 1 - alg 958 * 2 - :prov (optional) 959 * 3 - prov (optional) 960 * 4 - ,nextEntry (optional) 961 * 5 - nextEntry (optional) 962 */ 963 private static Pattern pattern = 964 Pattern.compile( 965 "\\s*([\\S&&[^:,]]*)(\\:([\\S&&[^,]]*))?\\s*(\\,(.*))?"); 966 } 967 968 /** 969 * Returns a {@code SecureRandom} object. 970 * 971 * In Android this is equivalent to get a SHA1PRNG from AndroidOpenSSL. 972 * 973 * Some situations require strong random values, such as when 974 * creating high-value/long-lived secrets like RSA public/private 975 * keys. To help guide applications in selecting a suitable strong 976 * {@code SecureRandom} implementation, Java distributions 977 * include a list of known strong {@code SecureRandom} 978 * implementations in the {@code securerandom.strongAlgorithms} 979 * Security property. 980 * <p> 981 * Every implementation of the Java platform is required to 982 * support at least one strong {@code SecureRandom} implementation. 983 * 984 * @return a strong {@code SecureRandom} implementation 985 * 986 * @throws NoSuchAlgorithmException if no algorithm is available 987 * 988 * @see Security#getProperty(String) 989 * 990 * @since 1.8 991 */ getInstanceStrong()992 public static SecureRandom getInstanceStrong() 993 throws NoSuchAlgorithmException { 994 995 @SuppressWarnings("removal") 996 String property = AccessController.doPrivileged( 997 new PrivilegedAction<>() { 998 @Override 999 public String run() { 1000 return Security.getProperty( 1001 "securerandom.strongAlgorithms"); 1002 } 1003 }); 1004 1005 if (property == null || property.isEmpty()) { 1006 throw new NoSuchAlgorithmException( 1007 "Null/empty securerandom.strongAlgorithms Security Property"); 1008 } 1009 1010 String remainder = property; 1011 while (remainder != null) { 1012 Matcher m; 1013 if ((m = StrongPatternHolder.pattern.matcher( 1014 remainder)).matches()) { 1015 1016 String alg = m.group(1); 1017 String prov = m.group(3); 1018 1019 try { 1020 if (prov == null) { 1021 return SecureRandom.getInstance(alg); 1022 } else { 1023 return SecureRandom.getInstance(alg, prov); 1024 } 1025 } catch (NoSuchAlgorithmException | 1026 NoSuchProviderException e) { 1027 } 1028 remainder = m.group(5); 1029 } else { 1030 remainder = null; 1031 } 1032 } 1033 1034 throw new NoSuchAlgorithmException( 1035 "No strong SecureRandom impls available: " + property); 1036 } 1037 1038 /** 1039 * Reseeds this {@code SecureRandom} with entropy input read from its 1040 * entropy source. 1041 * 1042 * @throws UnsupportedOperationException if the underlying provider 1043 * implementation has not overridden this method. 1044 * 1045 * @since 9 1046 */ reseed()1047 public void reseed() { 1048 if (threadSafe) { 1049 secureRandomSpi.engineReseed(null); 1050 } else { 1051 synchronized (this) { 1052 secureRandomSpi.engineReseed(null); 1053 } 1054 } 1055 } 1056 1057 /** 1058 * Reseeds this {@code SecureRandom} with entropy input read from its 1059 * entropy source with additional parameters. 1060 * <p> 1061 * Note that entropy is obtained from an entropy source. While 1062 * some data in {@code params} may contain entropy, its main usage is to 1063 * provide diversity. 1064 * 1065 * @param params extra parameters 1066 * @throws UnsupportedOperationException if the underlying provider 1067 * implementation has not overridden this method. 1068 * @throws IllegalArgumentException if {@code params} is {@code null}, 1069 * illegal or unsupported by this {@code SecureRandom} 1070 * 1071 * @since 9 1072 */ reseed(SecureRandomParameters params)1073 public void reseed(SecureRandomParameters params) { 1074 if (params == null) { 1075 throw new IllegalArgumentException("params cannot be null"); 1076 } 1077 if (threadSafe) { 1078 secureRandomSpi.engineReseed(params); 1079 } else { 1080 synchronized (this) { 1081 secureRandomSpi.engineReseed(params); 1082 } 1083 } 1084 } 1085 1086 // Declare serialVersionUID to be compatible with JDK1.1 1087 @java.io.Serial 1088 static final long serialVersionUID = 4940670005562187L; 1089 1090 // Retain unused values serialized from JDK1.1 1091 /** 1092 * @serial 1093 */ 1094 private byte[] state; 1095 /** 1096 * @serial 1097 */ 1098 @SuppressWarnings("serial") // Not statically typed as Serializable 1099 private MessageDigest digest = null; 1100 /** 1101 * @serial 1102 * 1103 * We know that the MessageDigest class does not implement 1104 * java.io.Serializable. However, since this field is no longer 1105 * used, it will always be NULL and won't affect the serialization 1106 * of the {@code SecureRandom} class itself. 1107 */ 1108 private byte[] randomBytes; 1109 /** 1110 * @serial 1111 */ 1112 private int randomBytesUsed; 1113 /** 1114 * @serial 1115 */ 1116 private long counter; 1117 } 1118