[JAVA] Versuchen Sie die Verschlüsselung / Entschlüsselung von Spring Security AES256-Zeichenfolgen

Überblick

Bei der Arbeit habe ich manchmal darüber nachgedacht, wie ich mit Projekten umgehen soll, die Datenverschlüsselung / -entschlüsselung voraussetzen. Deshalb werde ich schreiben, dass ich es als Erinnerung versucht habe.

Referenzinformationen

Englisch, aber die spring.io-Dokumentation ist hilfreich spring.io - Dokumentation zu Encryptors

Auf Japanisch ist das TERA SOLUNA-Dokument leicht zu lesen 6. Sicherheitsmaßnahmen von TERASOLUNA Server Framework für Java (5.x) >> 6.9. Verschlüsselung

Fazit (plötzlich)

Aus der Schlussfolgerung sieht es wie folgt aus (nur meine persönliche Meinung)

Methode Inhalt Kryptografischer Modus Verschlüsselungsstärke
noOpText Nicht verschlüsseln. Es wird als Mock für die Montage verwendet. Keiner Außer Frage
queryableText Verwenden Sie eine "standardmäßige" kennwortbasierte Verschlüsselung. Generieren Sie einen invarianten Wert. CBC Niedrig
text Verwenden Sie eine "standardmäßige" kennwortbasierte Verschlüsselung. Generieren Sie einen variablen Wert. CBC Während ~
delux Verwenden Sie eine "stärkere" kennwortbasierte Verschlüsselung. Generieren Sie einen variablen Wert. GCM Hoch

Überprüfung

Erstellen Sie das folgende Beispiel und probieren Sie es aus.

public class EncryptorTest {

  private static String secret = "1234";
  private static String salt = "5678";

  public static void main(String[] args) throws IOException {

    String text = "Hello";

    TextEncryptor encryptor1 = Encryptors.noOpText();
    String noOpTextEncryptText = encryptor1.encrypt(text);
    String noOpTextDecryptText = encryptor1.decrypt(noOpTextEncryptText);

    TextEncryptor encryptor2 = Encryptors.queryableText(secret, salt);
    String queryableTextEncryptText = encryptor2.encrypt(text);
    String queryableTextDecryptText = encryptor2.decrypt(queryableTextEncryptText);

    TextEncryptor encryptor3 = Encryptors.text(secret, salt);
    String textEncryptText = encryptor3.encrypt(text);
    String textDecryptText = encryptor3.decrypt(textEncryptText);

    TextEncryptor encryptor4 = Encryptors.delux(secret, salt);
    String deluxEncryptText = encryptor4.encrypt(text);
    String deluxDecryptText = encryptor4.decrypt(deluxEncryptText);

    System.out.println("noOpText()      :");
 System.out.println ("Verschlüsselungszeichenfolge:" + noOpTextEncryptText);
 System.out.println ("Entschlüsselungsbestätigung:" + noOpTextDecryptText);
    System.out.println("");
    System.out.println("queryableText() : ");
 System.out.println ("Verschlüsselungszeichenfolge:" + queryableTextEncryptText);
 System.out.println ("Entschlüsselungsbestätigung:" + queryableTextDecryptText);
    System.out.println("");
    System.out.println("text()          : ");
 System.out.println ("Verschlüsselungszeichenfolge:" + textEncryptText);
 System.out.println ("Entschlüsselungsbestätigung:" + textDecryptText);
    System.out.println("");
    System.out.println("delux()         : ");
 System.out.println ("Verschlüsselungszeichenfolge:" + deluxEncryptText);
 System.out.println ("Entschlüsselungsbestätigung:" + deluxDecryptText);
  }
noOpText()      :
Verschlüsselte Zeichenfolge: Hallo
Entschlüsselungsbestätigung: Hallo

queryableText() : 
Verschlüsselte Zeichenfolge: 524110739525b3f266a0064b4229a77d
Entschlüsselungsbestätigung: Hallo

text()          : 
Verschlüsselte Zeichenfolge: ced1eb40b88e691f502d548ed17752bff82592da917804ea66ea1a49bfa77033
Entschlüsselungsbestätigung: Hallo

delux()         : 
Verschlüsselte Zeichenfolge: 61e62f473d0cb228305081b927a3225d487a749b87af62071ad60dc6b27703410de45f7fbf
Entschlüsselungsbestätigung: Hallo

Obwohl die Zeichenlängen der Verschlüsselungen unterschiedlich sind, ist ersichtlich, dass die Entschlüsselung aus der Verschlüsselung jeweils möglich ist. Schauen wir uns hier die Logik der einzelnen Methoden an, um den Unterschied zu erkennen.

noOpText Wenn Sie eine Instanz mit Encryptors.noOpText () erstellen Die folgende Logik wird aufgerufen.

  private static final class NoOpTextEncryptor implements TextEncryptor {

    public String encrypt(String text) {
      return text;
    }

    public String decrypt(String encryptedText) {
      return encryptedText;
    }

  }

Ich bemerkte, dass dies nicht in Frage kam, aber ich tat nichts. Gibt es eine Verwendung dafür ...

queryableText

Dann ** queryableText **

	public static TextEncryptor queryableText(CharSequence password, CharSequence salt) {
		return new HexEncodingTextEncryptor(new AesBytesEncryptor(password.toString(),
				salt));
	}
	public AesBytesEncryptor(String password, CharSequence salt) {
 this (password, salt, null); // ← Das Argument hier ist null
	}

	public AesBytesEncryptor(String password, CharSequence salt,
			BytesKeyGenerator ivGenerator) {
		this(password, salt, ivGenerator, CipherAlgorithm.CBC);
	}

	public AesBytesEncryptor(String password, CharSequence salt,
			BytesKeyGenerator ivGenerator, CipherAlgorithm alg) {
		PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), Hex.decode(salt),
				1024, 256);
		SecretKey secretKey = newSecretKey("PBKDF2WithHmacSHA1", keySpec);
		this.secretKey = new SecretKeySpec(secretKey.getEncoded(), "AES");
		this.alg = alg;
		this.encryptor = alg.createCipher();
		this.decryptor = alg.createCipher();
		this.ivGenerator = ivGenerator != null ? ivGenerator : alg.defaultIvGenerator();
	}

text

Hinterlasse den Kommentar von ** queryableText ** und hinterlasse ** text **

	public static TextEncryptor text(CharSequence password, CharSequence salt) {
		return new HexEncodingTextEncryptor(standard(password, salt));
	}

	public static BytesEncryptor standard(CharSequence password, CharSequence salt) {
		return new AesBytesEncryptor(password.toString(), salt,
 KeyGenerators.secureRandom (16)); // ← Das Argument hier ist eine Zufallszahl
	}
	public AesBytesEncryptor(String password, CharSequence salt,
			BytesKeyGenerator ivGenerator) {
		this(password, salt, ivGenerator, CipherAlgorithm.CBC);
	}

	public AesBytesEncryptor(String password, CharSequence salt,
			BytesKeyGenerator ivGenerator, CipherAlgorithm alg) {
		PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), Hex.decode(salt),
				1024, 256);
		SecretKey secretKey = newSecretKey("PBKDF2WithHmacSHA1", keySpec);
		this.secretKey = new SecretKeySpec(secretKey.getEncoded(), "AES");
		this.alg = alg;
		this.encryptor = alg.createCipher();
		this.decryptor = alg.createCipher();
		this.ivGenerator = ivGenerator != null ? ivGenerator : alg.defaultIvGenerator();
	}

Was ist der Unterschied zwischen ** queryableText ** und ** text **? Der Unterschied besteht darin, ob der BytesKeyGenerator als ** null ** oder ** KeyGenerators.secureRandom (16) ** übergeben werden soll.

Da ** queryableText ** als ** null ** übergeben wird, wird jedes Mal dieselbe verschlüsselte Zeichenfolge generiert. Da ** Text ** KeyGenerators.secureRandom (16) ** passiert, wird jedes Mal eine andere Zufallszahl generiert, und als Ergebnis wird jedes Mal eine andere verschlüsselte Zeichenfolge generiert.

delux

Und schließlich ** Delux **

	public static TextEncryptor delux(CharSequence password, CharSequence salt) {
		return new HexEncodingTextEncryptor(stronger(password, salt));
	}

	public static BytesEncryptor stronger(CharSequence password, CharSequence salt) {
		return new AesBytesEncryptor(password.toString(), salt,
				KeyGenerators.secureRandom(16), CipherAlgorithm.GCM);
	}
	public AesBytesEncryptor(String password, CharSequence salt,
			BytesKeyGenerator ivGenerator, CipherAlgorithm alg) {
		PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), Hex.decode(salt),
				1024, 256);
		SecretKey secretKey = newSecretKey("PBKDF2WithHmacSHA1", keySpec);
		this.secretKey = new SecretKeySpec(secretKey.getEncoded(), "AES");
		this.alg = alg;
		this.encryptor = alg.createCipher();
		this.decryptor = alg.createCipher();
		this.ivGenerator = ivGenerator != null ? ivGenerator : alg.defaultIvGenerator();
	}

Was ist der Unterschied zwischen ** Text ** und ** Delux **? Der Unterschied besteht darin, ob für CipherAlgorithm ** CBC ** oder ** GCM ** angegeben ist.

Es wird allgemein gesagt, dass GCM (Galois / Counter Mode) parallel verarbeitet werden kann und effizienter als CBC ist. Trotz der Implementierung einer höheren Verschlüsselung als CBC gibt es keinen großen Unterschied in der Verarbeitungszeit.

Schreiben Sie tatsächlich einen Prozess, der die Verschlüsselung → Entschlüsselung 10.000 Mal wiederholt, und probieren Sie ihn mehrmals aus. Ich habe ** Text ** und ** Delux ** verglichen, aber die Verarbeitungszeit war fast gleich. (Fehler weniger als 1 Sekunde)

Impressionen

Ich hatte das Gefühl, dass es besser wäre, ** delux ** zu verwenden, wenn es keinen bestimmten Grund gibt. (Es gibt nur wenige Systeme, die behaupten, dass die Festplattenkapazität ... ist, weil die Datenlänge in dieser Zeit lang wird.)

Dies ist das Ende dieses Versuchs

Recommended Posts

Versuchen Sie die Verschlüsselung / Entschlüsselung von Spring Security AES256-Zeichenfolgen
Versuchen Sie es mit Spring Boot Security
Versuchen Sie die LDAP-Authentifizierung mit Spring Security (Spring Boot) + OpenLDAP
Versuchen Sie, mit Keycloak mit Spring Security SAML (Spring 5) zu arbeiten.
Informationen zur Spring Security-Authentifizierung
Spring Security erhöht 403 verboten
Versuchen Sie es mit Spring JDBC