Kennwort in Konfigurationsdateien verschlüsseln in Java
Bei der Verschlüsselung werden Klartextinformationen mithilfe eines Verschlüsselungsalgorithmus in Kombination mit einem Parameter namens Verschlüsselungsschlüssel in eine unlesbare Form umgewandelt. Das unlesbare Format wird häufig als ciphertext-Format bezeichnet. Nur wer den Entschlüsselungsschlüssel besitzt, kann die Daten entschlüsseln und den ursprünglichen Klartext wiederherstellen.
Wir können das Problem der Verschlüsselung von Passwörtern in Konfigurationsdateien in zwei folgende Unteraufgaben aufteilen.
- Verschlüsseln Sie das in der Datei enthaltene Klartextkennwort.
- Entschlüsseln Sie das aus der Datei eingelesene verschlüsselte Passwort.
Lassen Sie uns zuerst eine Konfigurationsdatei mit dem Namen config.properties im Pfad src/conf/ erstellen.
password = TestPassword123
Um nun die Konfigurationsdatei zu lesen, instanziieren Sie die Klasse Properties. Wir können eine Instanz der Klasse FileInputStream mit ihrem Konstruktor erstellen. Es nimmt den Pfad der Konfigurationsdatei als Eingabe. Jetzt wird eine Instanz der Eigenschaftenklasse verwendet, um die Eigenschaften zu laden. Verwenden Sie die Methode load, um die Eigenschaftendatei in die Klasse zu laden. Dabei wird die Instanz InputStreamReader als Parameter verwendet. Es wird IllegalArgumentException ausgelöst, wenn dieser Eingabestream eine fehlerhafte Unicode-Escape-Sequenz enthält, und IOException, wenn beim Lesen aus dem Eingabestream ein Fehler aufgetreten ist.
Verwenden Sie nach dem erfolgreichen Laden der Eigenschaften die Methode getProperty(), um nach der Eigenschaft mit dem angegebenen Schlüssel in der Eigenschaftenliste zu suchen. Die Methode gibt null zurück, wenn die Eigenschaften nicht gefunden werden können. Führen Sie eine externe Prüfung durch, um eine solche Situation zu behandeln, und lösen Sie IllegalArgumentException aus, wenn in der Datei ein Kennwort gefunden wird, das null ist.
salt wird mit einer beliebigen zufälligen Zeichenkette erstellt, die der KennwortZeichenkette hinzugefügt wird.
createSecretKey ist eine benutzerdefinierte Methode, die den SecretKeySpec-Schlüssel zurückgibt. Mit dem Schlüssel wird das Kennwort verschlüsselt und entschlüsselt. Die Methoden encrypt und decrypt sind benutzerdefinierte static Methoden, die in der Klasse Encryption angegeben wurden.
Unten finden Sie den Beispielcode, der dasselbe demonstriert.
package fileDataEncryption;
import static fileDataEncryption.Encryption.*;
import java.io.FileInputStream;
import java.util.Properties;
import javax.crypto.spec.SecretKeySpec;
public class ConfigFileEncryption {
public static void main(String[] args) throws Exception {
Properties properties = new Properties();
FileInputStream inputStream = new FileInputStream("src/conf/config.properties");
properties.load(inputStream);
String password = properties.getProperty("password");
if (password == null) {
throw new IllegalArgumentException("No such parameter present in config file");
}
byte[] salt = new String("12345678").getBytes();
int iterationCount = 40000;
int keyLength = 128;
SecretKeySpec key = createSecretKey(password.toCharArray(), salt, iterationCount, keyLength);
String originalPassword = password;
System.out.println("Original password: " + originalPassword);
String encryptedPassword = encrypt(originalPassword, key);
System.out.println("Encrypted password: " + encryptedPassword);
String decryptedPassword = decrypt(encryptedPassword, key);
System.out.println("Decrypted password: " + decryptedPassword);
}
}
Eine detaillierte Beschreibung der benutzerdefinierten Methoden in der Klasse Verschlüsselung finden Sie unten.
- Der
createSecretKeyist eine Funktion, die Parameter wiepassword,salt,iterationCountundkeyLengthakzeptiert.passwordist das eigentliche Passwort in der Konfigurationsdatei. In der Kryptographie sind einsaltzufällige Daten, die wir als zusätzliche Eingabe verwenden, die Daten, ein Kennwort oder eine Passphrase hasht. Die Verwendung vonsaltsdient zum Schutz von Passwörtern bei der Lagerung. Wir verwenden die VariableiterationCountals Anzahl der Iterationen, die ein Algorithmus ausführen soll. Das Verringern des Werts der Variablen beschleunigt die Startzeit und ist daher beim Testen hilfreich, erleichtert aber auch Brute-Force-Angreifern. Die VariablekeyLengthist die Länge des Schlüssels, den wir letztendlich ableiten müssen. Löst die Ausnahme aus, die von den verwendeten Methoden ausgelöst wurde. - Die Methode
getInstancedurchläuft die Liste der registrierten Sicherheitsanbieter, beginnend mit dem am meisten bevorzugten Anbieter. Es nimmt den Standardnamen des angeforderten Secret-Key-Algorithmus und gibt das neue ObjektSecretKeyFactoryzurück. Es wirdNullPointerExceptionausgelöst, wenn der angegebene Algorithmus null ist, undNoSuchAlgorithmException, wenn kein Anbieter eineSecretKeyFactorySpi-Implementierung für den angegebenen Algorithmus unterstützt. PBEKeySpecist ein Klassenkonstruktor, der ein Kennwort, einen Salt, eine Iterationszahl und eine abzuleitende Schlüssellänge zum Generieren vonPBEKeyvon PBE-Chiffren mit variabler Schlüsselgröße verwendet. Es wirdNullPointerExceptionausgelöst, wennsaltnullist, undIllegalArgumentException, wenn salt leer ist.generateSecretgeneriert aus der angegebenen Schlüsselspezifikation oder dem Schlüsselmaterial einSecretKey-Objekt. Es braucht die Angabe des geheimen Schlüssels. Es wirdInvalidKeySpecExceptionausgelöst, wenn die angegebene Spezifikation für diese Fabrik mit geheimen Schlüsseln nicht geeignet ist, um einen klassifizierten Schlüsselwert zu erzeugen.
Details zur Methode encrypt in der Klasse Encryption.
- Die Methode
encryptverwendet zwei Parameter, die zu verschlüsselnden Daten und den Schlüssel. Diese Methode löst Ausnahmen aus, die von untergeordneten Methoden ausgelöst werden. - Die Methode
getInstancedurchläuft die Liste der registrierten Sicherheitsanbieter, beginnend mit dem am meisten bevorzugten Anbieter. Es wird der Name der Transformation verwendet, dh AES / CBC / PKCS5Padding. Es wirdNoSuchAlgorithmExceptionausgelöst, wenn eine Änderung null und leer in einem ungültigen Format ist, undNoSuchPaddingException, wenn die Änderung ein Auffüllschema enthält, das nicht verfügbar ist. - Die Methode
initinitialisiert dieVerschlüsselungfür eine der folgenden vier Operationen: Verschlüsselung, Entschlüsselung, Schlüsselumbruch oder Schlüsselentpackung, abhängig vom Wert des Betriebsmodus.ENCRYPT_MODEin unserem Fall. Die Methode löstUnsupportedOperationExceptionaus, wenn der Betriebsmodus ungültig ist, undInvalidKeyException, wenn der angegebene Schlüssel unangemessen ist. - Der
getParametersgibt die mit dieser Chiffre verwendeten Parameter zurück. - Die
getParameterSpecgibt eine Spezifikation des Parameterobjekts zurück. Der ParameterparamSpecgibt die Spezifikationsklasse an, in der die Parameter zurückgegeben werden müssen. Beispielsweise könnte es dieDSAParameterSpec.classsein, die angibt, dass die Parameter in einer Instanz der KlasseDSAParameterSpeczurückgegeben werden müssen. - Die Methode
doFinalverschlüsselt oder entschlüsselt Daten in einer einteiligen Arbeit oder beendet eine mehrteilige Operation. Die Daten werden verschlüsselt oder entschlüsselt, je nachdem, wie wir die Verschlüsselung initialisieren. base64Encodeist eine private Methode, die das angegebene Bytearray mithilfe des CodierungsschemasBase64in eine Zeichenkette codiert. Die in der Methodedecryptverwendeten Funktionen ähneln der oben genannten Methode. Der einzige Unterschied besteht darin, dass sie sich je nach dem in der FunktionDECRYPT_MODEals Betriebsmodus angegebenenModusunterschiedlich verhalten.
package fileDataEncryption;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
public class Encryption {
public static SecretKeySpec createSecretKey(char[] password, byte[] salt, int iterationCount,
int keyLength) throws NoSuchAlgorithmException, InvalidKeySpecException {
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512");
PBEKeySpec keySpec = new PBEKeySpec(password, salt, iterationCount, keyLength);
SecretKey keyTmp = keyFactory.generateSecret(keySpec);
return new SecretKeySpec(keyTmp.getEncoded(), "AES");
}
public static String encrypt(String dataToEncrypt, SecretKeySpec key)
throws GeneralSecurityException, UnsupportedEncodingException {
Cipher pbeCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
pbeCipher.init(Cipher.ENCRYPT_MODE, key);
AlgorithmParameters parameters = pbeCipher.getParameters();
IvParameterSpec ivParameterSpec = parameters.getParameterSpec(IvParameterSpec.class);
byte[] cryptoText = pbeCipher.doFinal(dataToEncrypt.getBytes("UTF-8"));
byte[] iv = ivParameterSpec.getIV();
return base64Encode(iv) + ":" + base64Encode(cryptoText);
}
private static String base64Encode(byte[] bytes) {
return Base64.getEncoder().encodeToString(bytes);
}
public static String decrypt(String string, SecretKeySpec key)
throws GeneralSecurityException, IOException {
String iv = string.split(":")[0];
String property = string.split(":")[1];
Cipher pbeCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
pbeCipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(base64Decode(iv)));
return new String(pbeCipher.doFinal(base64Decode(property)), "UTF-8");
}
private static byte[] base64Decode(String property) throws IOException {
return Base64.getDecoder().decode(property);
}
}
Unten sehen Sie die Ausgabe des Codes, der zum Ver- und Entschlüsseln des Kennworts in der Konfigurationsdatei geschrieben wurde.
Original password: TestPassword123
Encrypted password: Hy7fbIwpyKgp0oileu+oLg==:WNRknMJz/8u8GmWlCZFPFA==
Decrypted password: TestPassword123
Rashmi is a professional Software Developer with hands on over varied tech stack. She has been working on Java, Springboot, Microservices, Typescript, MySQL, Graphql and more. She loves to spread knowledge via her writings. She is keen taking up new things and adopt in her career.
LinkedIn