在C语言中相当于我的openssl cmdline是什么?

时间:2020-02-28 18:24:36

标签: c openssl

我正在尝试在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&#232;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格式的理解。

2 个答案:

答案 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密码

相关问题