Le double cryptage du mot de passe avec SHA256 (les questions peuvent être expliquées dans les commentaires) vous donne de précieuses informations en échange de la honte rouge Alors, essayons de hacher les mots de passe ~~ cryptage ~~ avec BCrypt et PBKDF2 que vous avez introduits immédiatement. Cette fois, c'est l'édition BCrypt.
Cette fois, le hachage BCrypt ~~ encryption ~~ sera effectué en utilisant la même sécurité de ressort qui a été enseignée dans le commentaire de l'article ci-dessus. Je n'ai pas besoin de tout le Spring, donc j'ai emprunté uniquement le fichier spring-security jar de mvn repository. ..
String passStr = "password_desu_4";
String hashStr;
//Encoder
BCryptPasswordEncoder bpe = new BCryptPasswordEncoder();
hashStr = bpe.encode(passStr);
System.out.println("original string : " + passStr);
System.out.println("encoded by Bcrypt : " + hashStr);
//Authentification
boolean isMatch = bpe.matches(passStr, hashStr);
System.out.println("result : " + (isMatch ? "match" : "not match"));
intelligent!
Le résultat ressemble à ceci
original string : password_desu_4
encoded by Bcrypt : $2a$10$HQwFeyajSohLrmbHTEzJbuHzPgITU7CJ/fQbJfEBCkBJXz5lCk8ke
result : match
Vous pouvez définir la force en passant des entiers de 4 à 31 au constructeur de la classe BCryptPasswordEncoder. C'est la force, pas les temps d'étirement. Il semble étirer le multiplicateur de 2 pour l'argument.
Naturellement, le temps de traitement augmentera également de façon exponentielle. Bonne chance, c'est un ordinateur portable 32 bits i7 core.
= strength : 4, streach times : 16 ========
encoding time : 0.003 sec.
verifying time : 0.002 sec.
= strength : 5, streach times : 32 ========
encoding time : 0.004 sec.
verifying time : 0.004 sec.
= strength : 6, streach times : 64 ========
encoding time : 0.007 sec.
verifying time : 0.008 sec.
= strength : 7, streach times : 128 ========
encoding time : 0.015 sec.
verifying time : 0.014 sec.
= strength : 8, streach times : 256 ========
encoding time : 0.029 sec.
verifying time : 0.030 sec.
= strength : 9, streach times : 512 ========
encoding time : 0.058 sec.
verifying time : 0.060 sec.
= strength : 10, streach times : 1024 ========★ Force par défaut
encoding time : 0.118 sec.
verifying time : 0.117 sec.
= strength : 11, streach times : 2048 ========
encoding time : 0.240 sec.
verifying time : 0.231 sec.
= strength : 12, streach times : 4096 ========
encoding time : 0.462 sec.
verifying time : 0.463 sec.
= strength : 13, streach times : 8192 ========
encoding time : 0.924 sec.
verifying time : 0.926 sec.
= strength : 14, streach times : 16384 ========
encoding time : 1.847 sec.
verifying time : 1.840 sec.
= strength : 15, streach times : 32768 ========
encoding time : 3.702 sec.
verifying time : 3.691 sec.
= strength : 16, streach times : 65536 ========
encoding time : 7.440 sec.
verifying time : 7.402 sec.
= strength : 17, streach times : 131072 ========
encoding time : 14.867 sec.
verifying time : 14.776 sec.
= strength : 18, streach times : 262144 ========
encoding time : 30.416 sec.
verifying time : 29.593 sec.
= strength : 19, streach times : 524288 ========
encoding time : 60.6590 sec.
verifying time : 60.180 sec.
= strength : 20, streach times : 1048576 ========
Eh bien, le temps de traitement dépend de l'environnement, il n'aurait donc pas beaucoup de sens d'enregistrer le nombre exact de secondes dans mon environnement. Ainsi, la tendance qui peut être lue jusqu'ici est la suivante.
… C'est naturel car la quantité de traitement est doublée.
Donc si vous donnez une valeur théorique simplifiée
strength | temps de traitement |
---|---|
20 | 2 minutes |
21 | 4 minutes |
22 | 8 minutes |
23 | 16 minutes |
24 | 32 minutes |
25 | 1 heure 4 minutes |
26 | 2 heures 8 minutes |
27 | 4 heures 16 minutes |
28 | 8 heures 32 minutes |
29 | 17 heures 4 minutes |
30 | 1 jour et 10 heures 8 minutes |
31 | 2 jours et 20 heures 16 minutes |
La fonction exponentielle est effrayante.
Cette quantité de traitement est requise pour un mot de passe, bien qu'elle diminue naturellement si elle est effectuée dans un environnement de haute spécification. La force est de 10 (étirement 1024 fois) par défaut, mais même compte tenu du temps d'attente pour une connexion normale, je pense que la limite est d'environ 0,5 seconde (force = 12 dans cet environnement) au maximum.
Cela peut être une mesure de sécurité. Je l'ai réalisé moi-même. Je suis content de ne pas avoir essayé jusqu'au ~~ 31 ~~
import java.math.BigInteger;
import java.util.Date;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class CryptUtil {
/**
*Hashing avec Bcypt lors de la mesure du temps de traitement
* @param passStr chaîne de mot de passe
* @param force Le nombre de hachages. 4-31 (2 à la puissance)
*/
public static String testBcryptEncode(String passStr, int strength) {
//Heure de début
long startTime = (new Date()).getTime();
//Hashing avec BCrypt
BCryptPasswordEncoder bpe = new BCryptPasswordEncoder(strength);
String hashStr = bpe.encode(passStr);
//Heure de fin de hachage
long endTime = (new Date()).getTime();
String timeDelta = String.format("%.4f", ((float)(endTime - startTime) / 1000));
System.out.println("encoding time : " + timeDelta + " sec.");
return hashStr;
}
/**
*Authentifiez si le mot de passe brut et le hachage correspondent tout en mesurant le temps de traitement
* @param passStr raw
* @paramètre hashStr hash
* @param strength
*/
public static void testBcyptVerify(String passStr, String hashStr, int strength) {
//Heure de début
long startTime = (new Date()).getTime();
//Vérifiez si le mot de passe correspond au hachage
BCryptPasswordEncoder bpe = new BCryptPasswordEncoder(strength);
boolean isMatch = bpe.matches(passStr, hashStr);
//Heure de fin de la vérification
long endTime = (new Date()).getTime();
String timeDelta = String.format("%.4f", ((float)(endTime - startTime) / 1000));
if (isMatch) {
System.out.println("verifying time : " + timeDelta + " sec.");
} else {
}
}
public static void main(String[] args) {
String passStr = "password_desu_4";
String hashStr;
//Encodage et authentification simples
BCryptPasswordEncoder bpe = new BCryptPasswordEncoder();
hashStr = bpe.encode(passStr);
System.out.println("original string : " + passStr);
System.out.println("encoded by Bcrypt : " + hashStr);
boolean isMatch = bpe.matches(passStr, hashStr);
System.out.println("result : " + (isMatch ? "match" : "not match"));
System.out.println("");
//Mesure du temps pour chaque force
double streachTimes;
for (int strength=4; strength<=31; strength++) {
streachTimes = Math.pow(2, strength);
System.out.println("= strength : " + strength + ", streach times : " + String.format("%1$.0f", streachTimes) + " ========");
hashStr = testBcryptEncode(passStr, strength);
testBcyptVerify(passStr, hashStr, strength);
}
}
}
Recommended Posts