EVP 関数と対称キーを使用して、OpenSSL ライブラリで一部のデータを復号化できません。を使用するようにコマンドでデータを暗号化しopenssl enc
、付属の C++ コードで復号化します。これは機能します...ほとんど。
使用するデータに関係なく、復号化を実行した後、平文の 8 バイトの 2 番目のブロック (バイト 8 から 15) は正しくありませんが、ファイルの残りの部分は正しくなっています。私は 130 MB のファイルでもこれを行いました。これらのバイトを除いて、すべての 130 MB は完全に正しく、ファイル内の正しい位置にあります。
これは、ARM ターゲットと Ubuntu 12.04 (異なるライブラリ、異なるツールチェーン) でビルドした場合の両方で発生します。
問題のある短い完全なプログラムを次に示します。その下には、それを示す端末出力がいくつかあります。
#include <string>
#include <fstream>
#include <stdexcept>
#include <openssl/evp.h>
void decrypt_and_untar(const std::string& infile, const std::string& outfile)
{
unsigned char key[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
unsigned char iv[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
std::ifstream is(infile, std::ios_base::in | std::ios_base::binary);
std::ofstream os(outfile, std::ios_base::out | std::ios_base::binary);
auto ctx = EVP_CIPHER_CTX_new();
if (EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, key, iv))
{
const int BufferSize = 10240;
unsigned char enc_buff[BufferSize];
int bytes_in_enc_buff = 0;
unsigned char dec_buff[BufferSize + EVP_CIPHER_CTX_block_size(ctx)];
int bytes_in_dec_buff = 0;
while (!is.eof())
{
is.read(reinterpret_cast<char*>(enc_buff), BufferSize);
bytes_in_enc_buff = is.gcount();
if (bytes_in_enc_buff > 0)
{
if (EVP_DecryptUpdate(ctx, dec_buff, &bytes_in_dec_buff, enc_buff, bytes_in_enc_buff))
{
os.write(reinterpret_cast<char*>(dec_buff), bytes_in_dec_buff);
bytes_in_enc_buff = 0;
bytes_in_dec_buff = 0;
}
else
throw std::runtime_error("Failed DecryptUpdate.");
}
}
if (EVP_DecryptFinal_ex(ctx, dec_buff, &bytes_in_dec_buff))
os.write(reinterpret_cast<char*>(dec_buff), bytes_in_dec_buff);
else
throw std::runtime_error("Failed DecryptFinal.");
}
else
{
throw std::runtime_error("Failed DecryptInit.");
}
EVP_CIPHER_CTX_free(ctx);
}
int main(int argc, char* argv[])
{
if (argc == 3)
decrypt_and_untar(argv[1], argv[2]);
return 0;
}
これは実際の問題のデモです。すべてゼロの 1 メガのファイルを作成し、暗号化、復号化してから、od
. これを複数回実行すると、これらの 8 つの間違ったバイトの値が実行ごとに変化します...
~/workspace/test_crypto/Debug$ dd if=/dev/zero of=plain.original bs=1024 count=1024
1024+0 records in
1024+0 records out
1048576 bytes (1.0 MB) copied, 0.00154437 s, 679 MB/s
~/workspace/test_crypto/Debug$ od -t x1 plain.original
0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
4000000
~/workspace/test_crypto/Debug$ /usr/bin/openssl enc -aes-256-cbc -salt -in plain.original -out encrypted -K 00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF -iv 0011223344556677
~/workspace/test_crypto/Debug$ ./test_crypto encrypted plain
~/workspace/test_crypto/Debug$ od -t x1 plain
0000000 00 00 00 00 00 00 00 00 00 40 02 0d 18 93 b8 bf
0000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
4000000
~/workspace/test_crypto/Debug$