Created
January 22, 2013 05:54
-
-
Save relax-more/4592436 to your computer and use it in GitHub Desktop.
SecureRandomがどの程度Secureなのかを確認した時のメモ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
結論。 | |
SecureRandomのインスタンスを生成する時に明示的にSeedを与えない場合は実行環境に関する下記のようなデータや | |
タイムスタンプをHashにしてseed としている。 | |
System.getProperties() | |
InetAddress.getLocalHost().toString().getBytes() | |
File(p.getProperty("java.io.tmpdir")) | |
途中で例外が発生した場合はそのExceptionのByteCode | |
参考 | |
■調査のための導入資料+TomcatでのSessionの実装から乱数生成を学ぶ | |
http://d.hatena.ne.jp/higher_tomorrow/searchdiary?word=%CD%F0%BF%F4 | |
■javaのシステムプロパティとはなんぞや | |
http://www.ne.jp/asahi/hishidama/home/tech/java/application.html#version_system.property | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// メモのため抜粋 | |
// 乱数を生成する際に seed が登録されていない場合、SeedGenerator#getSystemEntropy | |
// でSeedの取得を行なっている | |
package sun.security.provider; | |
public final class SecureRandom extends SecureRandomSpi implements java.io.Serializable { | |
/** | |
* Generates a user-specified number of random bytes. | |
* | |
* @param bytes the array to be filled in with random bytes. | |
*/ | |
public synchronized void engineNextBytes(byte[] result) { | |
int index = 0; | |
int todo; | |
byte[] output = remainder; | |
if (state == null) { | |
if (seeder == null) { | |
// 乱数を生成する際に seed が登録されていない場合、 | |
seeder = new SecureRandom(SeedGenerator.getSystemEntropy()); | |
seeder.engineSetSeed(engineGenerateSeed(DIGEST_SIZE)); | |
} | |
byte[] seed = new byte[DIGEST_SIZE]; | |
seeder.engineNextBytes(seed); | |
state = digest.digest(seed); | |
} | |
// Use remainder from last time | |
int r = remCount; | |
if (r > 0) { | |
// How many bytes? | |
todo = (result.length - index) < (DIGEST_SIZE - r) ? | |
(result.length - index) : (DIGEST_SIZE - r); | |
// Copy the bytes, zero the buffer | |
for (int i = 0; i < todo; i++) { | |
result[i] = output[r]; | |
output[r++] = 0; | |
} | |
remCount += todo; | |
index += todo; | |
} | |
// If we need more bytes, make them. | |
while (index < result.length) { | |
// Step the state | |
digest.update(state); | |
output = digest.digest(); | |
updateState(state, output); | |
// How many bytes? | |
todo = (result.length - index) > DIGEST_SIZE ? | |
DIGEST_SIZE : result.length - index; | |
// Copy the bytes, zero the buffer | |
for (int i = 0; i < todo; i++) { | |
result[index++] = output[i]; | |
output[i] = 0; | |
} | |
remCount += todo; | |
} | |
// Store remainder for next time | |
remainder = output; | |
remCount %= DIGEST_SIZE; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// メモのため抜粋 | |
// seedGenerator#getSystemEntropy では | |
// MessageDigestを下記の3つの値とRuntimeのメモリを利用して更新している | |
// System.getProperties() | |
// InetAddress.getLocalHost().toString().getBytes() | |
// File(p.getProperty("java.io.tmpdir")) | |
// また、途中で例外が発生した場合はそのExceptionのByteCodeで更新を行なっている | |
package sun.security.provider; | |
abstract class SeedGenerator{ | |
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(); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment