sun.security.provider
abstract class: SeedGenerator [javadoc |
source]
java.lang.Object
sun.security.provider.SeedGenerator
Direct Known Subclasses:
ThreadedSeedGenerator, NativeSeedGenerator, URLSeedGenerator
This class generates seeds for the cryptographically strong random
number generator.
The seed is produced using one of two techniques, via a computation
of current system activity or from an entropy gathering device.
In the default technique the seed is produced by counting the
number of times the VM manages to loop in a given period. This number
roughly reflects the machine load at that point in time.
The samples are translated using a permutation (s-box)
and then XORed together. This process is non linear and
should prevent the samples from "averaging out". The s-box
was designed to have even statistical distribution; it's specific
values are not crucial for the security of the seed.
We also create a number of sleeper threads which add entropy
to the system by keeping the scheduler busy.
Twenty such samples should give us roughly 160 bits of randomness.
These values are gathered in the background by a daemon thread
thus allowing the system to continue performing it's different
activites, which in turn add entropy to the random seed.
The class also gathers miscellaneous system information, some
machine dependent, some not. This information is then hashed together
with the 20 seed bytes.
The alternative to the above approach is to acquire seed material
from an entropy gathering device, such as /dev/random. This can be
accomplished by setting the value of the "securerandom.source"
security property (in the Java security properties file) to a URL
specifying the location of the entropy gathering device.
In the event the specified URL cannot be accessed the default
mechanism is used.
The Java security properties file is located in the file named
<JAVA_HOME>/lib/security/java.security.
<JAVA_HOME> refers to the value of the java.home system property,
and specifies the directory where the JRE is installed.
- author:
Joshua - Bloch
- author:
Gadi - Guy
| Field Summary |
|---|
| static final String | URL_DEV_RANDOM | |
| static final String | URL_DEV_URANDOM | |
| Method from sun.security.provider.SeedGenerator Detail: |
public static void generateSeed(byte[] result) {
// Static initializer to hook in selected or best performing generator
String egdSource = SunEntries.getSeedSource();
// Try the URL specifying the source
// e.g. file:/dev/random
//
// The URL file:/dev/random or file:/dev/urandom is used to indicate
// the SeedGenerator using OS support, if available.
// On Windows, the causes MS CryptoAPI to be used.
// On Solaris and Linux, this is the identical to using
// URLSeedGenerator to read from /dev/random
if (egdSource.equals(URL_DEV_RANDOM) || egdSource.equals(URL_DEV_URANDOM)) {
try {
instance = new NativeSeedGenerator();
if (debug != null) {
debug.println("Using operating system seed generator");
}
} catch (IOException e) {
if (debug != null) {
debug.println("Failed to use operating system seed "
+ "generator: " + e.toString());
}
}
} else if (egdSource.length() != 0) {
try {
instance = new URLSeedGenerator(egdSource);
if (debug != null) {
debug.println("Using URL seed generator reading from "
+ egdSource);
}
} catch (IOException e) {
if (debug != null)
debug.println("Failed to create seed generator with "
+ egdSource + ": " + e.toString());
}
}
// Fall back to ThreadedSeedGenerator
if (instance == null) {
if (debug != null) {
debug.println("Using default threaded seed generator");
}
instance = new ThreadedSeedGenerator();
}
instance.getSeedBytes(result);
}
Fill result with bytes from the queue. Wait for it if it isn't ready. |
abstract byte getSeedByte()
|
void getSeedBytes(byte[] result) {
for (int i = 0; i < result.length; i++) {
result[i] = getSeedByte();
}
}
|
static byte[] getSystemEntropy() {
byte[] ba;
final MessageDigest md;
try {
md = MessageDigest.getInstance("SHA");
} catch (NoSuchAlgorithmException nsae) {
throw new InternalError("internal error: SHA-1 not available.");
}
// The current time in millis
byte b =(byte)System.currentTimeMillis();
md.update(b);
java.security.AccessController.doPrivileged
(new java.security.PrivilegedAction< Void >() {
public Void run() {
try {
// System properties can change from machine to machine
String s;
Properties p = System.getProperties();
Enumeration< ? > e = p.propertyNames();
while (e.hasMoreElements()) {
s =(String)e.nextElement();
md.update(s.getBytes());
md.update(p.getProperty(s).getBytes());
}
md.update
(InetAddress.getLocalHost().toString().getBytes());
// The temporary dir
File f = new File(p.getProperty("java.io.tmpdir"));
String[] sa = f.list();
for(int i = 0; i < sa.length; i++)
md.update(sa[i].getBytes());
} catch (Exception ex) {
md.update((byte)ex.hashCode());
}
// get Runtime memory stats
Runtime rt = Runtime.getRuntime();
byte[] memBytes = longToByteArray(rt.totalMemory());
md.update(memBytes, 0, memBytes.length);
memBytes = longToByteArray(rt.freeMemory());
md.update(memBytes, 0, memBytes.length);
return null;
}
});
return md.digest();
}
Retrieve some system information, hashed. |