我正在尝试在C中实现以下openssl命令行:
openssl enc -aes-256-cbc -d -in /tmp/out_enc -K \
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA \
-iv 0 -nopad -p
命令行输出:
key=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
iv =00000000000000000000000000000000
<CONNECTION_REQUEST ATS_ID="2" ATP_SEQ_ID="1" REGISTRATION_ID="Y2G5R52S8PP6YX47" SERIAL_NUMBER="724574802" SPC_PRODUCT_TITLE="SPC5300" SPC_FW_VERSION="3.8.5 - R.31629" ATS_NAME="Système (ATS) 2" ATP1_ID="2" ATP1_UID="34" ATP1_NAME="Principal ATP 1" ATP1_COMMS_INTERFACE="1" ATP1_DEST="1, 192.168.1.62:52000" ATP1_CATEGORY="50"/>�z
这是我相当于C的语言:
long
_ast_crypt_decrypt_generic(unsigned char* ciphertext, long cipherlen, unsigned char* plaintext, const EVP_CIPHER *cipher) {
long result = 0;
/* A 256 bit key */
unsigned char *key = (unsigned char *)"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
/* A 128 bit IV */
unsigned char *iv = (unsigned char *)"0000000000000000";
EVP_CIPHER_CTX *ctx = NULL;
int len;
long plaintext_len;
if (cipher) {
/* Create and initialise the context */
if (!(ctx = EVP_CIPHER_CTX_new())) {
g_warning("AstCrypt : EVP_CIPHER_CTX_new failed");
goto end;
}
if (1 != EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv)) {
g_warning("AstCrypt : EVP_DecryptInit_ex");
}
EVP_CIPHER_CTX_set_padding(ctx, 0);
if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, cipherlen)) {
g_warning("AstCrypt : EVP_DecryptUpdate");
goto end;
}
plaintext_len = len;
if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len)) {
g_warning("AstCrypt : EVP_DecryptFinal_ex failed");
goto end;
}
plaintext_len += len;
result= plaintext_len;
}
else {
g_warning("AstCrypt : Failed to get the openssl elements.");
}
end:
if (ctx)
EVP_CIPHER_CTX_free(ctx);
return result;
}
long plainSize = _ast_crypt_decrypt_generic(headerData, headerLength, bPlain, EVP_aes_256_cbc());
//fwrite(bPlain, plainSize, 1, stdout);
以前的代码示例未正确解密数据(在C中)。
您有什么想法我想念吗?
可能缺少对openssl库中的key / iv格式的理解。
答案 0 :(得分:1)
答案是密钥/ iv必须用十六进制表示:
以下预期工作:
unsigned char key[] =
{ 0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA,
0xAA, 0xAA, 0xAA, 0xAA,0 };
//unsigned char key[] = {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
/* A 128 bit IV */
unsigned char iv[] =
{ 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,0 };
答案 1 :(得分:0)
问题是您假设密钥是“密码”的直接副本。您在该命令行中执行的操作是将密钥指定为十六进制字符串。因此,您需要做的是将您的“密码”从十六进制字符串转换为密钥缓冲区。在您的示例中,您应该将每个字节设置为十六进制值“ 0xAA”。
因为您直接传递了密钥,所以不需要MD5参数(传递给函数或openssl)。
如果您想使用密码而不是“十六进制字符串”,则需要以某种方式将其哈希到密钥缓冲区中。这是MD5参数的来源。您可以使用类似PBKDF2的东西(尽管我将使用openssl默认SHA256而不是MD5作为哈希函数)。
例如openssl enc -aes-256-cbc -pbkdf2 -k密码