OpenJDK i Sun čtou z /dev/urandom
, nikoli /dev/random
, alespoň na počítači, kde jsem testoval (OpenJDK JRE 6b27 a Sun JRE 6.26 na Debian squeeze amd64). Z nějakého důvodu oba otevřou /dev/random
také, ale nikdy z toho nečtěte. Takže články na blogu, které jste četli, byly buď chybné, nebo byly použity na jinou verzi, než je moje (a zřejmě i vaše).
Můžete zkontrolovat, zda vaše čte z /dev/random
nebo /dev/urandom
jeho sledováním:
strace -o a.strace -f -e file java A
a vyhledejte příslušnou část trasování:
21165 open("/dev/random", O_RDONLY) = 6
…
21165 open("/dev/urandom", O_RDONLY) = 7
…
21165 read(7, "\322\223\211\262Zs\300\345\3264l\254\354[\6wS\[email protected]", 20) = 20
…
Nebojte se, /dev/urandom
je naprosto v pořádku pro kryptografii.
SecureRandom od Java může použijte /dev/random, ale jen krátce.
Konkrétně jej používá pouze při generování počátečních informací, a to buď explicitním voláním SecureRandom.generateSeed()
nebo prvním voláním na nextInt()
Chcete-li tedy zopakovat svůj příklad bash, můžete provést následující a mělo by se to zablokovat.
import java.security.SecureRandom;
public class A {
public static void main(String[] args) {
SecureRandom sr;
int out = 0;
for (int i = 0; i < 1<<20 ; i++) {
sr = new SecureRandom();
out ^= sr.nextInt();
}
System.out.println(out);
}
}
Nejen proto, abychom udrželi staré vlákno naživu, ale některým lidem možná unikla důležitá část dlouhého příběhu za tím... Jednalo se o dobře známou nechvalně známou a přetrvávající chybu při používání /dev/urandom od verze Java 1.4 po verze 1.7. Viz odkazy níže:
http://bugs.java.com/view_bug.do?bug_id=6202721
http://bugs.java.com/view_bug.do?bug_id=4705093
Za to vím, že to bylo konečně vyřešeno v Javě 8, jak uvádí Oracle:https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8.html
SHA1PRNG a NativePRNG byly opraveny, aby správně respektovaly vlastnosti zdroje zdroje SecureRandom v souboru java.security. (Nejasné řešení pomocí file:///dev/urandom a file:/dev/./urandomis již není vyžadováno.)