2016-05-10 14 views
1

なぜ...これらの2つのbashコマンドの出力が異なるのはなぜですか?

KEY=$(echo -ne "\x2e\x9e\x93\x83\x8c\xf5\xeb\x78\x2f\x9e\xd7\xbe\xaa\x27\xf6\x1f\xa5\x35\xe3\x37\x4c\x78\x22\xc9\x11\x24\x20\x22\xa6\x3e\x28\x30") 
echo -e "$(echo -en aws4_request | openssl dgst -sha256 -hmac "$KEY" -binary | xxd)" 

生産...

0000000: d77d 4050 8184 cbd2 44f0 f6c2 5b95 39d0 .}@P....D...[.9. 
0000010: d9b4 bf25 a7ec a4f8 0dac cc00 6b2b 67d4 ...%........k+g. 

と...

echo -ne "$(echo -en aws4_request | openssl dgst -sha256 -hmac "$KEY" -binary)" | xxd 

生成(そのバイト28は、第一の出力に比べて不足している注意してください) ?私はOpenSSLからの出力は、サブシェルの外xxdのためにパイプされていることは問題ないはず理解したよう

0000000: d77d 4050 8184 cbd2 44f0 f6c2 5b95 39d0 .}@P....D...[.9. 
0000010: d9b4 bf25 a7ec a4f8 0dac cc6b 2b67 d4 ...%.......k+g. 

答えて

4

強力なCの基盤のため、UNIXの文字列はNUL '\0'文字を保持できません。 00バイトの生のバイナリデータを処理する場合は、結果を文字列に格納しないようにする必要があります。ファイルとパイプラインには、00バイトが入っているのが安全です。ここで

echo -e "$(echo -en aws4_request | openssl dgst -sha256 -hmac "$KEY" -binary | xxd)" 

OpenSSLが埋め込ま00バイトでバイナリデータを出してくれる。その出力を直接xxdにパイプするので、データは完全に保持されます。00はそのままです。

echo -ne "$(echo -en aws4_request | openssl dgst -sha256 -hmac "$KEY" -binary)" | xxd 

ここで、opensslの出力はxxdにパイプされる前に文字列に格納されます。 $(...)操作は、NUL文字を文字列に正常に格納できないため、NUL文字を取り除きます。それを取り除かなかった場合、最初のNULは文字列の終わりを知らせます。

エコーのレイヤーを削除することができます。 echo "$(command)"は、commandを書き込む複雑な方法です。

echo -n aws4_request | openssl dgst -sha256 -hmac "$KEY" -binary | xxd 
2

問題は、ダイジェストがバイナリであることである(具体的には、ゼロバイトを含む)、シェル(例えばechoなど)引数としてそのコマンドのC文字列を通過しながら、これらは、ゼロを含めることはできませんバイト(/ヌル文字)。欠けているバイトを見ると、それは16進数で "00"です。あなたは、文字列「aws4_request888」でさえもより明確にこれを見ることができます:

$ KEY=$(echo -ne "\x2e\x9e\x93\x83\x8c\xf5\xeb\x78\x2f\x9e\xd7\xbe\xaa\x27\xf6\x1f\xa5\x35\xe3\x37\x4c\x78\x22\xc9\x11\x24\x20\x22\xa6\x3e\x28\x30") 
$ echo -e "$(echo -en aws4_request888 | openssl dgst -sha256 -hmac "$KEY" -binary | xxd)" 
0000000: 3939 a1b7 b334 22e3 7ab6 d7f0 32be 2f62 99...4".z...2./b 
0000010: e353 72f9 3152 a923 a3e3 0000 0006 85fb .Sr.1R.#........ 
$ echo -ne "$(echo -en aws4_request888 | openssl dgst -sha256 -hmac "$KEY" -binary)" | xxd 
0000000: 3939 a1b7 b334 22e3 7ab6 d7f0 32be 2f62 99...4".z...2./b 
0000010: e353 72f9 3152 a923 a3e3 0685 fb   .Sr.1R.#..... 

この場合、ダイジェストは3 NULLバイトがあったが、それらはすべて消えました。

実際の唯一の解決策は、シェル引数、変数などを介してバイナリデータを渡すことを避けることです(また、$KEYも含まれます)。

シェルでバイナリデータを処理する必要がある場合は、それを格納する前に16進数に変換して(hexvar=$(somethingthatproducesbinary | xxd -p)、バイナリに戻って使用するようにしてください(たとえば、 echo "$hexvar" | xxd -r -p | somethingthatreadsbinary)。

関連する問題