当您没有指明 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

显然我得到了与之前相同的 salt、key 和 iv。

第一个问题是:从什么意义上说“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

而且我没有提供 iv 也得到了同样的结果!

salt=237F07334625A768
key=F746D2B53EB82F7129BAEB2FCE2C310F
iv =BA28DBA00442BD4BACEBCAE7C01BA412

现在,虽然我可以看到加密文件中的盐,并且向程序提供了密钥,但我没有输入 iv,也没有看到加密文件中的 iv。

因此第二个问题是:解密程序如何知道解密文件所需的 iv?或者换句话说,如果 iv 嵌入在加密文件中(就像 salt 一样),它是如何做到的?

答案1

密钥和 IV 都是使用 PBKDF 从密码计算得出的。对于 OpenSSL,使用的方法是EVP_BytesToKey。这是一个类似于 PBKDF1 的函数,它不使用多次迭代。盐是 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
}

相关内容