Problema: Sembra che quando il server viene riavviato, Bcrypt.hashpw accetta 100 ms per decrittografare la password. Tuttavia, dopo un po 'di tempo (senza pattern) improvvisamente le prestazioni di Bcrypt.hashpw aumentano da 100ms a 10s di secondi. Non c'è una ragione ovvia per questo.
Il problema è /dev/random
a volte isolati e quando lo fa appare essere casuale :) La cosa più confuso è che durante il tentativo di verificare come funziona si incorrerà contro l'Effetto Observer vale a dire durante il tentativo di osserva il comportamento casuale che stai generando entropia e questo può portare a un sacco di confusione, ovvero i miei risultati non saranno uguali ai tuoi ecc. Questo è anche il motivo per cui sembra che non ci siano pattern ..
Mostrerò il problema e mostrarti come ricrearlo (entro limiti ragionevoli) sui tuoi server in modo da poter testare le soluzioni. Proverò a fornire un paio di correzioni, si noti che questo è su Linux ma lo stesso problema si verificherà su qualsiasi sistema che richiede entropia per generare numeri casuali e si esaurisce.
Su Linux /dev/random
è un flusso di byte casuali. Come si legge dal flusso si esaurisce l'entropia disponibile. Quando raggiunge un certo punto legge dal blocco /dev/random
. Si può vedere a disposizione l'entropia di utilizzare questo comando
cat /proc/sys/kernel/random/entropy_avail
Se si esegue il seguente script bash e anche monitorare entropy_avail
avrete avviso che l'entropia tuffi drammaticamente come lo script bash consuma.
while :
do
cat /dev/random > /dev/null
done
Questo dovrebbe anche dare un suggerimento su come ricreare questo problema sui server cioè eseguire lo script bash sopra per ridurre l'entropia disponibile e il problema si manifesterà.
Se volete vedere quanti byte al secondo sistema è la creazione si possibile utilizzare pv
per misurarla cioè
pv /dev/random
Se si lascia pv
esecuzione ha un effetto, è consumando il flusso casuale di byte che significa che altri servizi potrebbero iniziare a bloccare. Notare che pv
sta anche visualizzando il suo output, quindi potrebbe anche essere disponibile in aumento sul sistema :).
Su sistemi con poca o nessuna entropia utilizzando pv /dev/random
sembrerà glaciale lento. Ho anche sperimentato che a volte le VM hanno grossi problemi con la generazione di entropia.
per ricreare il problema creare utilizzare la seguente classe ...
import java.security.SecureRandom;
import org.mindrot.jbcrypt.BCrypt;
public class RandTest {
public static void main(String[] args) {
SecureRandom sr = new SecureRandom();
int out = 0;
String password = "very-strong-password-1729";
String hashed;
for (int i = 0; i < 200000 ; i++) {
hashed = BCrypt.hashpw(password, BCrypt.gensalt());
//If we print, we're generating entroy :) System.out.println(hashed);
}
}
}
Ho scaricato bcrypt in una directory locale. Ho compilato ed eseguito come segue
javac -cp ./jBCrypt-0.4/src/ RandTest.java
java -cp ./jBCrypt-0.4/src/:. RandTest
Se quindi si esegue lo script bash dalla prima, mentre runnng RandTest
vedrete grandi pause in cui il sistema sta bloccando in attesa di più l'entropia. Se si esegue strace
vedrete il seguente ...
1067 [pid 22481] open("/dev/random", O_RDONLY|O_LARGEFILE) = 12
11068 [pid 22481] fstat64(12, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 8), ...}) = 0
11069 [pid 22481] fcntl64(12, F_GETFD) = 0
11070 [pid 22481] fcntl64(12, F_SETFD, FD_CLOEXEC) = 0
.....
11510 [pid 22481] read(12, "\320\244\317RB\370", 8) = 6
Il programma sta leggendo dal /dev/random
. Il problema con l'entropia di prova è e potresti generarne di più mentre provi a testarlo, ad esempio l'effetto Observer.
correzioni
La prima soluzione consiste nel modificare dall'utilizzo /dev/random
a /dev/urandom
cioè
time java -Djava.security.egd=file:///dev/./urandom -cp ./jBCrypt-0.4/src/:. RandTest
Una soluzione alternativa è quella di ricreare il dispositivo /dev/random
come dispositivo /dev/urandom
. Puoi trovare come fare questo forma la pagina man, invece di crearli ...
mknod -m 644 /dev/random c 1 8
mknod -m 644 /dev/urandom c 1 9
chown root:root /dev/random /dev/urandom
cancelliamo uno e falso cioè
rm /dev/random
mknod -m 644 /dev/random c 1 9
chown root:root /dev/random
/dev/random
è ora effettivamente /dev/urandom
La cosa fondamentale da ricordare sta testando dati casuali che richiede entroy dal sistema sei test è difficile a causa dell'effetto Observer.
Collegare un profiler e capire quale parte impiega così tanto tempo. –
Salve @ m-deinum, lo abbiamo già fatto e abbiamo scoperto che il problema riguarda la libreria stessa. Questo non spiega perché la libreria funzioni bene per un po 'di tempo e poi si innalza (e rimane così) a 10 secondi o più. –
Quale libreria e quale parte della libreria ... Il fatto che sia * la libreria * non chiarisca le cose, potresti voler essere un po 'più specifico su quale parte della libreria. Metodo ecc. –