使用 C++ 的 openssl 3des

openssl 3des with c++

我想使用 C++ 中的 openssl 库来解密数据。

我有密钥和 IV 以及编码的 base64 字符串。

我没看懂文档,头文件(openssl/des.h)中的所有解密方法都需要3个密钥。

我已经通过以下 python 代码成功实现了结果。

from pyDes import *
import base64

key = base64.b64decode("****")
iv = base64.b64decode("***")
enc = base64.b64decode("******")
encryptor = triple_des(key, CBC, iv)
plain = encryptor.decrypt(enc)
print(plain.decode("utf-8"))

我想使用 C++ 代码和 OpenSSL 库获得相同的结果。

3DES 使用三个密钥。您正在使用的 python 函数可能从您传递的 key 参数派生出三个键,可能将其分成三部分。

要使用 OpenSSL 功能,您必须生成 3 个密钥,每个密钥 8 个字节(或 24 个字节的密钥分成 3 个)。

我修改了我找到的代码 here 以使用 ECB 而不是 CBC。但是,出于安全原因,您应该考虑使用 CBC,甚至 AES 加密而不是 3DES。

该示例仅显示如何使用带有硬编码键的 DES_ecb3_encrypt 函数。在最终解决方案中,您必须使用良好的 RNG 生成自己的密钥。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/des.h>

/* Triple DES key for Encryption and Decryption */
DES_cblock Key1 = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 };
DES_cblock Key2 = { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 };
DES_cblock Key3 = { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33 };
DES_key_schedule SchKey1,SchKey2,SchKey3;

/* Print Encrypted and Decrypted data packets */
void print_data(const char *tittle, const void* data, int len);

int main()
{
    /* Input data to encrypt */
    DES_cblock input_data = {0x01, 0x02, 0x03, 0x04, 0x05, 0x6, 0x7, 0x8};

    /* Check for Weak key generation */
    if ( -2 == (DES_set_key_checked(&Key1, &SchKey1) || DES_set_key_checked(&Key2, &SchKey2) || DES_set_key_checked(&Key3, &SchKey3)))
    {
        printf(" Weak key ....\n");
        return 1;
    }

    /* Buffers for Encryption and Decryption */
    DES_cblock cipher;
    DES_cblock text;

    /* Triple-DES ECB Encryption */
    DES_ecb3_encrypt(&input_data, &cipher, &SchKey1, &SchKey2, &SchKey3, DES_ENCRYPT);

    /* Triple-DES ECB Decryption */
    DES_ecb3_encrypt(&cipher, &text, &SchKey1, &SchKey2, &SchKey3, DES_DECRYPT);

    /* Printing and Verifying */
    print_data("\n Original ", (const void*) input_data, sizeof(input_data));
    print_data("\n Encrypted", (const void*) cipher, sizeof(input_data));
    print_data("\n Decrypted", (const void*) text, sizeof(input_data));

    return 0;
}
void print_data(const char *tittle, const void* data, int len)
{
    printf("%s : ",tittle);
    const unsigned char * p = (const unsigned char*)data;
    int i = 0;

    for (; i<len;++i)
        printf("%02X ", *p++);

    printf("\n");
}

OpenSSL reference:

void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, 
        DES_key_schedule *ks1, DES_key_schedule *ks2, 
        DES_key_schedule *ks3, int enc);

DES_ecb3_encrypt() encrypts/decrypts the input block by using three-key Triple-DES encryption in ECB mode. This involves encrypting the input with ks1, decrypting with the key schedule ks2, and then encrypting with ks3. This routine greatly reduces the chances of brute force breaking of DES and has the advantage of if ks1, ks2 and ks3 are the same, it is equivalent to just encryption using ECB mode and ks1 as the key.