
Angenommen, ich verschlüssele mit dem Schlüssel „1234“ eine Datei, die „abcd“ enthält, mit:
openssl enc -iv BABA -aes128 -in file.txt -out file.enc -p
Ich bekomme:
salt=1B929D9049534D22
key=0326A1E8F4875B26FE2D04E02425C5AD
iv =BABA0000000000000000000000000000
So weit, ist es gut.
Ich kann die Datei entschlüsseln mit:
openssl enc -d -aes128 -iv BABA -in file1.enc -out file1.dec.txt -p
Und natürlich erhalte ich dasselbe Salt, denselben Schlüssel und denselben IV wie zuvor.
Die erste Frage lautet: In welchem Sinne ist „0326A1E8F4875B26FE2D04E02425C5AD“ der „Schlüssel“?
Welche Beziehung besteht zu meinem Schlüssel „1234“? (Es sieht aus wie ein MD5-Hash. Aber... wovon?)
Weiter geht's. Jetzt mache ich das Gleiche (gleicher Klartext, gleicher Schlüssel), ohne den IV anzugeben:
openssl enc -aes128 -in file.txt -out file2.enc -p
Ich bekomme:
salt=237F07334625A768
key=F746D2B53EB82F7129BAEB2FCE2C310F
iv =BA28DBA00442BD4BACEBCAE7C01BA412
Jetzt entschlüssele ich mit:
openssl enc -d -aes128 -in file2.enc -out file2.dec.txt -p
und ich bekomme dasselbe, OHNE die IV anzugeben!
salt=237F07334625A768
key=F746D2B53EB82F7129BAEB2FCE2C310F
iv =BA28DBA00442BD4BACEBCAE7C01BA412
Obwohl ich nun das Salt in der verschlüsselten Datei sehen kann und dem Programm den Schlüssel gebe, gebe ich den IV weder ein, noch kann ich den IV in der verschlüsselten Datei sehen.
Daher lautet die zweite Frage: Woher kennt das Entschlüsselungsprogramm den IV, der zum Entschlüsseln der Datei erforderlich ist? Oder anders ausgedrückt: Wenn der IV in die verschlüsselte Datei eingebettet ist (wie das Salt), wie wird das gemacht?
Antwort1
Der Schlüssel und der IV werden beide mithilfe eines PBKDF aus dem Passwort berechnet. Im Fall von OpenSSL wird die folgende Methode verwendet EVP_BytesToKey
. Dies ist eine Funktion ähnlich PBKDF1, die nicht viele Iterationen verwendet. Das Salt ist ein Eingabeparameter für das PBKDF. Es stellt sicher, dass Schlüssel und IV immer unterschiedlich sind, auch wenn Sie dasselbe Passwort verwenden.
Sie können sich den Quellcode ansehenHierum eine Vorstellung davon zu bekommen, wie die Schlüssel- und IV-Ableitung erfolgt ( EVP_BytesToKey
ist nicht so gut beschrieben, es handelt sich um einen proprietären Mechanismus innerhalb von OpenSSL).
Grundsätzlich gilt bei der Verschlüsselung:
openssl_encrypt(password: string, plaintext: bytes): bytes
{
salt:bytes = random(8) # 8 bytes = 64 bits
iterations:int = 1
key:bytes, iv:bytes = pbkdf(password, iterations, salt)
ciphertext:bytes = encrypt_aes_cbc_pkcs7padding(key, iv, plaintext)
encoded_ciphertext:bytes = "Salted__" | salt | ciphertext
return encoded_ciphertext
}
und das ist die Entschlüsselung:
openssl_decrypt(password:string, encoded_ciphertext:bytes)
{
salt:bytes = take(encoded_ciphertext, from: 8, size: 8) # 8 bytes = 64 bits
ciphertext:bytes = take(encoded_ciphertext, from: 16, size: sizeof(encoded_ciphertext - 16)
iterations:int = 1
key:bytes, iv:bytes = pbkdf(password, iterations, salt)
plaintext:bytes = decrypt_aes_cbc_pkcs7padding(key, iv, ciphertext)
return plaintext
}