Doppelte Verschlüsselung des Passworts mit SHA256 (Fragen können in den Kommentaren erklärt werden) gibt Ihnen wertvolle Einblicke im Austausch gegen rote Schande Also werde ich versuchen, die Passwörter ~~ Verschlüsselung ~~ mit BCrypt und PBKDF2 zu hashen, die Sie sofort eingeführt haben. Diesmal ist BCrypt Edition.
Dieses Mal wird das BCrypt-Hashing mit der gleichen Federsicherheit durchgeführt, die im Kommentar des obigen Artikels beschrieben wurde. Ich brauche nicht den ganzen Frühling, also habe ich nur das Spring-Sicherheitsglas von [mvn repository] ausgeliehen (https://mvnrepository.com/artifact/org.springframework.security/spring-security-core/5.1.1.RELEASE). ..
String passStr = "password_desu_4";
String hashStr;
//Kodieren
BCryptPasswordEncoder bpe = new BCryptPasswordEncoder();
hashStr = bpe.encode(passStr);
System.out.println("original string : " + passStr);
System.out.println("encoded by Bcrypt : " + hashStr);
//Authentifizierung
boolean isMatch = bpe.matches(passStr, hashStr);
System.out.println("result : " + (isMatch ? "match" : "not match"));
Clever!
Das Ergebnis sieht so aus
original string : password_desu_4
encoded by Bcrypt : $2a$10$HQwFeyajSohLrmbHTEzJbuHzPgITU7CJ/fQbJfEBCkBJXz5lCk8ke
result : match
Sie können die Stärke festlegen, indem Sie Ints von 4 bis 31 an den Konstruktor der BCryptPasswordEncoder-Klasse übergeben. Es ist Stärke, keine Dehnungszeiten. Es scheint den Multiplikator von 2 für das Argument zu strecken.
Natürlich wird auch die Verarbeitungszeit exponentiell zunehmen. Viel Glück, es ist ein 32-Bit-i7-Core-Laptop.
= 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 ========★ Standardstärke
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 ========
Nun, die Verarbeitungszeit hängt von der Umgebung ab, daher wäre es nicht sinnvoll, die genaue Anzahl von Sekunden in meiner Umgebung aufzuzeichnen. Die Tendenz, die bisher gelesen werden kann, ist wie folgt.
… Es ist natürlich, weil sich der Verarbeitungsaufwand verdoppelt.
Wenn Sie also einen vereinfachten theoretischen Wert angeben
strength | Verarbeitungszeit |
---|---|
20 | 2 Minuten |
21 | 4 Minuten |
22 | 8 Minuten |
23 | 16 Minuten |
24 | 32 Minuten |
25 | 1 Stunde 4 Minuten |
26 | 2 Stunden 8 Minuten |
27 | 4 Stunden 16 Minuten |
28 | 8 Stunden 32 Minuten |
29 | 17 Stunden 4 Minuten |
30 | 1 Tag und 10 Stunden 8 Minuten |
31 | 2 Tage und 20 Stunden 16 Minuten |
Exponentialfunktion ist beängstigend.
Dieser Verarbeitungsaufwand ist für ein Kennwort erforderlich, wird jedoch in einer Umgebung mit hohen Spezifikationen natürlich verringert. Die Stärke beträgt standardmäßig 10 (1024-mal strecken), aber selbst unter Berücksichtigung der Wartezeit zum Zeitpunkt der normalen Anmeldung denke ich, dass das Limit höchstens etwa 0,5 Sekunden (Stärke = 12 in dieser Umgebung) beträgt.
Dies kann eine Sicherheitsmaßnahme sein. Ich habe es für mich selbst realisiert. Ich bin froh, dass ich es erst ~~ 31 ~~ versucht habe
import java.math.BigInteger;
import java.util.Date;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class CryptUtil {
/**
*Hashing mit Bcypt während der Messung der Verarbeitungszeit
* @param passStr Passwortzeichenfolge
* @Parameterstärke Die Anzahl der Hashings. 4-31 (2 hoch)
*/
public static String testBcryptEncode(String passStr, int strength) {
//Startzeit
long startTime = (new Date()).getTime();
//Hashing mit BCrypt
BCryptPasswordEncoder bpe = new BCryptPasswordEncoder(strength);
String hashStr = bpe.encode(passStr);
//Hashing Endzeit
long endTime = (new Date()).getTime();
String timeDelta = String.format("%.4f", ((float)(endTime - startTime) / 1000));
System.out.println("encoding time : " + timeDelta + " sec.");
return hashStr;
}
/**
*Authentifizieren Sie, ob das unformatierte Kennwort und der Hash übereinstimmen, während Sie die Verarbeitungszeit messen
* @param passStr raw
* @param hashStr hash
* @param strength
*/
public static void testBcyptVerify(String passStr, String hashStr, int strength) {
//Startzeit
long startTime = (new Date()).getTime();
//Überprüfen Sie, ob das Passwort mit dem Hash übereinstimmt
BCryptPasswordEncoder bpe = new BCryptPasswordEncoder(strength);
boolean isMatch = bpe.matches(passStr, hashStr);
//Endzeit der Überprüfung
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;
//Einfache Codierung und Authentifizierung
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("");
//Zeitmessung für jede Stärke
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