當您不指明時,IV 是如何嵌入加密檔案中的?

當您不指明時,IV 是如何嵌入加密檔案中的?

假設我使用密鑰“1234”加密包含“abcd”的檔案:

openssl enc -iv BABA -aes128 -in file.txt -out file.enc -p

我得到:

salt=1B929D9049534D22
key=0326A1E8F4875B26FE2D04E02425C5AD
iv =BABA0000000000000000000000000000

到目前為止,一切都很好。

我可以使用以下方法解密該檔案:

openssl enc -d -aes128 -iv BABA -in file1.enc -out file1.dec.txt -p

顯然我得到了和以前一樣的鹽、鑰匙和靜脈注射。

第一個問題是:在什麼意義上「0326A1E8F4875B26FE2D04E02425C5AD」是「密鑰」?

它和我的密鑰「1234」有什麼關係? (它看起來是一個 md5 哈希值。但是…是什麼?)

我們繼續。現在我做同樣的事情(相同的明文,相同的金鑰)而不提供 iv:

openssl enc -aes128 -in file.txt -out file2.enc -p

我得到:

salt=237F07334625A768
key=F746D2B53EB82F7129BAEB2FCE2C310F
iv =BA28DBA00442BD4BACEBCAE7C01BA412

現在我用以下方法解密:

openssl enc -d -aes128 -in file2.enc -out file2.dec.txt -p

我在不提供靜脈注射的情況下得到了同樣的結果!

salt=237F07334625A768
key=F746D2B53EB82F7129BAEB2FCE2C310F
iv =BA28DBA00442BD4BACEBCAE7C01BA412

現在,雖然我可以看到加密檔案中的 salt,並且我提供了程式金鑰,但我沒有鍵入 iv,也看不到加密檔案中的 iv。

因此第二個問題是:解密程式如何知道解密檔案所需的iv?或者,換句話說,如果 iv 嵌入到加密檔案中(就像鹽一樣),那麼它是如何完成的?

答案1

密鑰和 IV 都是使用 PBKDF 根據密碼計算得出的。對於 OpenSSL,使用的方法是EVP_BytesToKey。這是一個類似 PBKDF1 的函數,它不使用很多迭代。 salt 是 PBKDF 的輸入參數。它確保密鑰和 IV 始終不同,即使您使用相同的密碼也是如此。

你可以看一下原始碼這裡了解金鑰和 IV 派生是如何發生的(EVP_BytesToKey沒有很好地描述,它是 OpenSSL 中的專有機制)。

基本上,在加密過程中:

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
}

這是解密:

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
}

相關內容