
「abcd」を含むファイルをキー「1234」で暗号化するとします。
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
そして明らかに、以前と同じソルト、キー、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
そして、点滴をしなくても同じ結果が得られます!
salt=237F07334625A768
key=F746D2B53EB82F7129BAEB2FCE2C310F
iv =BA28DBA00442BD4BACEBCAE7C01BA412
現在、暗号化されたファイル内の salt は表示でき、プログラムにキーを提供していますが、iv は入力しておらず、暗号化されたファイル内の iv も表示できません。
したがって、2 番目の質問は、復号化プログラムは、ファイルの復号化に必要な iv をどのようにして知るのかということです。言い換えると、iv が暗号化されたファイルに埋め込まれている場合 (ソルトのように)、どのように行われるのでしょうか。
答え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
}