web-dev-qa-db-ja.com

OpenSSL AES暗号化のソルトはどこにありますか?

OpenSSLが生成されたソルトをAES暗号化データにどのように、どこに挿入するかを知りたいです。どうして? Javaクラスのデータを暗号化し、OpenSSLを使用してそれらを復号化できることを保証する必要があります。

たとえば、パスフレーズ"abc"を使用して生成されたこの暗号化されたbase64文字列があるとします。

U2FsdGVkX1+tfvgUkjErP6j2kUAVwWZzNlaAmTqhzTk= 

# generated with "openssl enc -aes-256-cbc -a"

それを復号化するには、次のように使用できます。

echo U2FsdGVkX1+tfvgUkjErP6j2kUAVwWZzNlaAmTqhzTk= | openssl enc -d -a -aes-256-cbc -p

# enc -d
#     decryption
# -a 
#     input is base64
# -aes-256-cbc 
#     the aes algorithm used in encryption
# -p 
#     print salt, key and iv params

"abc"パスフレーズを使用してこれを実行すると、次の結果になります。

salt=AD7EF81492312B3F
key=DEC1F5A1E5EAAA7DD539BBCFCEB1BB18868B974186ED056C27046ADD3A752C8B
iv =95A770DE9E0130E77C8E5D796D1B4EF5
Polaco

これで、AESがデータを復号化するには、キーと初期化ベクトルが必要であることがわかりました。

OpenSSLの場合、 the manual は、キーがパスフレーズとソルトから生成され、初期化ベクトルがキー自体から派生していることを示します(手動で指定されていない場合)。つまり、生成されたデータにはIVが必要ではありませんが、ソルトが必要です。そうしないと、復号化のキーが正しく生成されません。

つまり、ポイントは、ソルトはどこにあり、結果のデータにどのように挿入されるのかということです。生成されたデータに対していくつかの基本的な分析(base64からデコードして16進値を出力)を行うと、結果のデータにソルトが付加または付加されていないことがわかりますが、どういうわけか存在します。

# salt: AD7EF81492312B3F
echo U2FsdGVkX1+tfvgUkjErP6j2kUAVwWZzNlaAmTqhzTk= | openssl enc -d -base64 | od -x                                                                                                                                                                                         
0000000 6153 746c 6465 5f5f 7ead 14f8 3192 3f2b
0000020 f6a8 4091 c115 7366 5636 9980 a13a 39cd
0000040

Salt "AD7E..."は、暗号化されたデータに直接存在しないことがわかります。何らかの変化が起こったようです。

ソルトはペアで切り替えられ、バイト#9からデータに挿入されるように見えます。これは、OpenSSLのみが実装する一般的な方法ですか?

# salt:                     AD7E F814 9231 2B3F
# switch pair by pair:      7EAD 14F8 3192 3F2B
# data: 6153 746c 6465 5f5f 7ead 14f8 3192 3f2b f6a8 4091 c115 7366 5636 9980 a13a 39cd

編集する

Thomas Porninが述べたように、ここでの問題はod -xが生データを出力することです。私のコンピューターはx86_64なので、データはリトルエンディアンであり、Saltは「スワップ」されているように見えます。 endianness がどのようにトリッキーであるかを忘れていました。今は常にod -t x1を使用することを覚えています

とにかく、9バイト目にソルトを挿入することが一般的な方法なのか、OpenSSL固有の実装なのかを知りたいと思っています。最初のバイトがSalted__の文字であることにも気付きました

18
bcap

はい、変換が発生しました:endianness...

バイト8から15を見てください:7ead 14f8 3192 3f2b。それはあなたの塩です。これは、odの既知の癖です:16ビット単位でデータをデコードしリトルエンディアン、それらを「数値的に」表示しますなので、これは明らかにバイトスワップを引き起こします。

使用する od -t x1より良い出力を得るために。

編集:他の質問に答えるために、OpenSSLが行うことは標準的でも一般的でもありません。それは単に「OpenSSLが常に行ったこと」です。十分に文書化されていません。

13
Thomas Pornin

Opensslの以前のバージョンでは、非常に弱い鍵導出プロセスを使用して、パスワードから暗号化鍵を導出していました。 opensslのバージョン1.1.1は、ランダムに生成されたソルトを使用したPBKDF2を使用した鍵の派生と、sha256ハッシュの複数の反復(デフォルトでは10,000)をサポートするようになりました。この回答はopensslバージョン1.1.1に基づいており、ランダムに生成されたソルトを使用してPBKDF2を使用し、sha256を10,000回反復して、パスワードからキー(およびiv)を導出します。

最初に、opensslを使用して、上記の鍵導出プロセスを使用して、平文を暗号化します。

echo -n 'this is the plaintext' | openssl aes-256-cbc -e -salt -pbkdf2 -iter 10000 -out ciphertext.enc -p

上記のopensslコマンドで使用されるオプションの詳細については、 https://www.openssl.org/docs/man1.1.1/man1/openssl-enc.html を参照してください。 -pオプションは、opensslにsalt、key、ivを表示させるために使用されます。パスワードを入力した後、-pオプションは以下を生成します。

salt=7EFCC65B38A0ACAA
key=5A81937CD1FBB6A32C2DB9BDB2AAE5CB47D82198ED861C0C1AF6CAA18B21295E
iv =D829763E72F2DFEEBEFAA30E12E29266

xxdを使用して、opensslによって生成された暗号文ファイルのバイトを表示できます。

xxd ciphertext.enc 

これにより、以下が生成されます。

00000000: 5361 6c74 6564 5f5f 7efc c65b 38a0 acaa  Salted__~..[8...
00000010: 5d4d 957f 380e 71ba 4a1c 0913 43ee 5791  ]M..8.q.J...C.W.
00000020: 0c29 c5c8 9f0c 1c0e f8d5 c453 e7c1 b3b6  .).........S....

ご覧のとおり、ファイルの最初の8バイトは文字列「Salted__」のASCIIコードです。次に、次の8バイトはソルト自体です。これは、平文を暗号化するために上記で使用されたopensslコマンドの-pオプションによって生成される出力に示されているものと同じです。

次のコマンドを使用して、暗号文ファイルを復号化できます。

openssl aes-256-cbc -d -salt -pbkdf2 -iter 10000 -in ciphertext.enc -p

ここでも、-pオプションを使用して、salt、key、ivを表示します。パスワードを入力した後、-pオプションは以前と同じsalt、key、ivを表示します。次に、暗号文が復号化され、元の平文が生成されます。

salt=0E2FC30932D8371F
key=88DA1F925B6B64A36844FC0EC33A2DBB01B6F72C98AE36602217D00E126AC237
iv =1D5F234D86FA64C208A59FC1BA3AC915
this is the plaintext

価値があるのは、ivはPBKDF2関数とキーによって生成されることです。 PBKDF2関数は48バイトを生成します。バイト0〜31がキーです。バイト32-47はivです。詳細については、 https://crypto.stackexchange.com/questions/3298/is-there-a-standard-for-openssl-interoperable-aes-encryption/79855#79855 を参照してください。

0
mti2935