c++openssldestripledes

openssl 3des with c++


I want to use the openssl library in C++ to decrypt data.

I have the key and IV and the encoded base64 string.

I couldn't make it through the documentation, all decryption methods in the header file (openssl/des.h) take 3 keys.

I've managed to achieve the result with the following python code.

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"))

I want to get the same result using C++ code and OpenSSL library.


Solution

  • 3DES uses three keys. The python function you are using probably derives three keys from the key argument you pass, probably splitting it in three parts.

    To use the OpenSSL function, you have to generate 3 keys with 8 bytes each (or a 24 bytes key split in 3).

    I adapted the code I found here to use ECB instead of CBC. But, for security reasons, you should consider using CBC, or even AES encryption instead of 3DES.

    The example only shows how to use the DES_ecb3_encrypt function with hard coded keys. In a final solution, you have to generate your own keys, using a good 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.