コマンドライン ツール openssl に問題があるか、C++ コードに問題があります。どちらが間違っているかわかりませんが、両方の方法を使用してパスフェーズとソルトからキーと IV を生成すると、同じキー/IV 値が得られません。コードまたはコマンドラインにタイプミスや問題はありますか? openssl 0.9.8i のバージョンが壊れていますか? コマンドラインには反復カウント値を渡す機能がないため、nround 値 1 を使用しています。一致するはずですが、そうではなく、どこに間違いがあるのか わかりません。
-----------------次のコードは、文字列 XYZ を 2OG7CNt/SjFEZ4RM3ZS4ZA== として正しく暗号化します。
EVP_CIPHER_CTX ctx;
unsigned char acOutbuf[cMaxEncryptLen + EVP_MAX_BLOCK_LENGTH + 1];
int nOutLen;
std::string strDecrypt;
// Key and IV values.
const unsigned char pcCode[] = "f7bUtborBWdBIUkZuLr9oVGzGsc7Y6AMMe7U3z+AQo8";
const unsigned char pcSalt[] = {0x78,0x01,0x3E,0x00,0xD8,0x04,0x3E,0x00};
unsigned char acKey[EVP_MAX_KEY_LENGTH + 1];
unsigned char acIV[EVP_MAX_IV_LENGTH + 1];
// Load all the encryption ciphers and lookup the one we want to use.
OpenSSL_add_all_algorithms();
const EVP_CIPHER *cipher = EVP_get_cipherbyname("aes-256-cbc");
// Generate HashKey for the password.
int nrounds = 1;
int nCnt = EVP_BytesToKey(cipher, EVP_sha1(), pcSalt, pcCode, sizeof(pcCode), nrounds, acKey, acIV);
char *pcPassword = const_cast<char *> (strPassword.c_str());
nBase64DecodeCnt = strPassword.length();
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, cipher, NULL, acKey, acIV, 1);
if(!EVP_CipherUpdate(&ctx, acOutbuf, &nOutLen, (const unsigned char *) pcPassword, nBase64DecodeCnt))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return strDecrypt;
}
if(!EVP_CipherFinal_ex(&ctx, acOutbuf, &nOutLen))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return strDecrypt;
}
strDecrypt.assign((const char *) acOutbuf, nOutLen);
EVP_CIPHER_CTX_cleanup(&ctx);
return strDecrypt;
-----------------次のコードは、2OG7CNt/SjFEZ4RM3ZS4ZA== を XYZ として復号化します ---------------------- -
EVP_CIPHER_CTX ctx;
unsigned char acOutbuf[cMaxEncryptLen + EVP_MAX_BLOCK_LENGTH + 1];
int nOutLen;
std::string strDecrypt;
// Key and IV values.
const unsigned char pcCode[] = "f7bUtborBWdBIUkZuLr9oVGzGsc7Y6AMMe7U3z+AQo8";
const unsigned char pcSalt[] = {0x78,0x01,0x3E,0x00,0xD8,0x04,0x3E,0x00};
unsigned char acKey[EVP_MAX_KEY_LENGTH + 1];
unsigned char acIV[EVP_MAX_IV_LENGTH + 1];
// Load all the encryption ciphers and lookup the one we want to use.
OpenSSL_add_all_algorithms();
const EVP_CIPHER *cipher = EVP_get_cipherbyname("aes-256-cbc");
// Generate HashKey for the password.
int nrounds = 1;
int nCnt = EVP_BytesToKey(cipher, EVP_sha1(), pcSalt, pcCode, sizeof(pcCode), nrounds, acKey, acIV);
// Convert the base64 password string back into a real password.
int nBase64DecodeCnt;
char *pcPassword = Base64ToByteStream ((char *) strPassword.c_str(), (int) strPassword.length(), &nBase64DecodeCnt);
EVP_CIPHER_CTX_init(&ctx);
EVP_CipherInit_ex(&ctx, cipher, NULL, acKey, acIV, 0);
if(!EVP_CipherUpdate(&ctx, acOutbuf, &nOutLen, (const unsigned char *) pcPassword, nBase64DecodeCnt))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return strDecrypt;
}
if(!EVP_CipherFinal_ex(&ctx, acOutbuf, &nOutLen))
{
EVP_CIPHER_CTX_cleanup(&ctx);
return strDecrypt;
}
strDecrypt.assign((const char *) acOutbuf, nOutLen);
EVP_CIPHER_CTX_cleanup(&ctx);
return strDecrypt;
openssl コマンドライン ツールを使用して復号化と暗号化を行うことはできますが、コマンドラインを使用して正しく生成されたキーと iv を取得できないことに注意してください。
---- Encrypts correct -----
echo -n XYZ | openssl enc -e -a -aes-256-cbc -K eaa4d33f9f6a9a8e543c0ae80eef651b675ef50682e5f144f1c140269531ddb2 -iv e94c989252a82fcb6b934752c0f3702b
Produces : 2OG7CNt/SjFEZ4RM3ZS4ZA==
---- Decrypts correct to XYZ ----
echo 2OG7CNt/SjFEZ4RM3ZS4ZA== | openssl.exe enc -d -a -aes-256-cbc -K eaa4d33f9f6a9a8e543c0ae80eef651b675ef50682e5f144f1c140269531ddb2 -iv e94c989252a82fcb6b934752c0f3702b
Produces : XYZ
----- Does not produce the correct key and IV --------
openssl enc -aes-256-cbc -md sha1 -S 78013E00D8043E00 -P -pass pass:f7bUtborBWdBIUkZuLr9oVGzGsc7Y6AMMe7U3z+AQo8
salt=78013E00D8043E00
key=718D65A221F0B2F12B6C92B7E54501DD63A8E156E03CA0E98E73653B1D0F58E5
iv =A5FDF910766E727E2100FA09B7578685