mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8246613: Choose the default SecureRandom algo based on registration ordering
Fixed java.security.Provider and SecureRandom to use the 1st registered SecureRandom service Reviewed-by: weijun, mullan
This commit is contained in:
parent
edefd3c198
commit
0b8f18beda
3 changed files with 220 additions and 102 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -259,35 +259,51 @@ public class SecureRandom extends java.util.Random {
|
|||
}
|
||||
|
||||
private void getDefaultPRNG(boolean setSeed, byte[] seed) {
|
||||
String prng = getPrngAlgorithm();
|
||||
if (prng == null) {
|
||||
// bummer, get the SUN implementation
|
||||
prng = "SHA1PRNG";
|
||||
Service prngService = null;
|
||||
String prngAlgorithm = null;
|
||||
for (Provider p : Providers.getProviderList().providers()) {
|
||||
// SUN provider uses the SunEntries.DEF_SECURE_RANDOM_ALGO
|
||||
// as the default SecureRandom algorithm; for other providers,
|
||||
// Provider.getDefaultSecureRandom() will use the 1st
|
||||
// registered SecureRandom algorithm
|
||||
if (p.getName().equals("SUN")) {
|
||||
prngAlgorithm = SunEntries.DEF_SECURE_RANDOM_ALGO;
|
||||
prngService = p.getService("SecureRandom", prngAlgorithm);
|
||||
break;
|
||||
} else {
|
||||
prngService = p.getDefaultSecureRandomService();
|
||||
if (prngService != null) {
|
||||
prngAlgorithm = prngService.getAlgorithm();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// per javadoc, if none of the Providers support a RNG algorithm,
|
||||
// then an implementation-specific default is returned.
|
||||
if (prngService == null) {
|
||||
prngAlgorithm = "SHA1PRNG";
|
||||
this.secureRandomSpi = new sun.security.provider.SecureRandom();
|
||||
this.provider = Providers.getSunProvider();
|
||||
if (setSeed) {
|
||||
this.secureRandomSpi.engineSetSeed(seed);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
SecureRandom random = SecureRandom.getInstance(prng);
|
||||
this.secureRandomSpi = random.getSecureRandomSpi();
|
||||
this.provider = random.getProvider();
|
||||
if (setSeed) {
|
||||
this.secureRandomSpi.engineSetSeed(seed);
|
||||
}
|
||||
this.secureRandomSpi = (SecureRandomSpi)
|
||||
prngService.newInstance(null);
|
||||
this.provider = prngService.getProvider();
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
// never happens, because we made sure the algorithm exists
|
||||
// should not happen
|
||||
throw new RuntimeException(nsae);
|
||||
}
|
||||
}
|
||||
if (setSeed) {
|
||||
this.secureRandomSpi.engineSetSeed(seed);
|
||||
}
|
||||
// JDK 1.1 based implementations subclass SecureRandom instead of
|
||||
// SecureRandomSpi. They will also go through this code path because
|
||||
// they must call a SecureRandom constructor as it is their superclass.
|
||||
// If we are dealing with such an implementation, do not set the
|
||||
// algorithm value as it would be inaccurate.
|
||||
if (getClass() == SecureRandom.class) {
|
||||
this.algorithm = prng;
|
||||
this.algorithm = prngAlgorithm;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -620,13 +636,6 @@ public class SecureRandom extends java.util.Random {
|
|||
instance.provider, algorithm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@code SecureRandomSpi} of this {@code SecureRandom} object.
|
||||
*/
|
||||
SecureRandomSpi getSecureRandomSpi() {
|
||||
return secureRandomSpi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the provider of this {@code SecureRandom} object.
|
||||
*
|
||||
|
@ -868,30 +877,6 @@ public class SecureRandom extends java.util.Random {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a default PRNG algorithm by looking through all registered
|
||||
* providers. Returns the first PRNG algorithm of the first provider that
|
||||
* has registered a {@code SecureRandom} implementation, or null if none of
|
||||
* the registered providers supplies a {@code SecureRandom} implementation.
|
||||
*/
|
||||
private static String getPrngAlgorithm() {
|
||||
for (Provider p : Providers.getProviderList().providers()) {
|
||||
// For SUN provider, we use SunEntries.DEFF_SECURE_RANDOM_ALGO
|
||||
// as the default SecureRandom algorithm; for other providers,
|
||||
// we continue to iterate through to the 1st SecureRandom
|
||||
// service
|
||||
if (p.getName().equals("SUN")) {
|
||||
return SunEntries.DEF_SECURE_RANDOM_ALGO;
|
||||
}
|
||||
for (Service s : p.getServices()) {
|
||||
if (s.getType().equals("SecureRandom")) {
|
||||
return s.getAlgorithm();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lazily initialize since Pattern.compile() is heavy.
|
||||
* Effective Java (2nd Edition), Item 71.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue