1

Trying to do CBC TripleDES encryption/decryption with OpenSSL in C++. Encryption seems to work ok, but when I try to decrypt I get wrong result as some chaotic set of characters.

Encryption/Decryption

#define DES_BLOCK_SIZE 8

unsigned char* start3DES (const unsigned char* text, int length, int mode) { // 1 - encryption | 0 - 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 = { 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 } ;
    DES_key_schedule SchKey1, SchKey2, SchKey3;

//    unsigned char indata[DES_BLOCK_SIZE]; // unsigned char[8]
//    unsigned char outdata[DES_BLOCK_SIZE]; // unsigned char[8]

    DES_cblock input_data = {0xc3, 0x07, 0xd1, 0xe5, 0x66, 0x99, 0x18, 0x74 };

    if ( -2 == (DES_set_key_checked(&Key1, &SchKey1) || DES_set_key_checked(&Key2, &SchKey2) || DES_set_key_checked(&Key3, &SchKey3)))
    {
        LOGE(" Weak key \n");
        return nullptr;
    }

    DES_cblock cipher;
    DES_cblock input_text;
    DES_cblock enc_cipher; // unsigned char[8]
    DES_cblock out_buf;

    unsigned char *cipher_out;
    cipher_out = new unsigned char[length];

    DES_cblock cblock = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; // Initialization Vector (IV)

    // 1 - encryption | 0 - decryption
    if(mode == DES_ENCRYPT) {
        memset(cblock,0,sizeof(DES_cblock));
        DES_set_odd_parity(&cblock);

        int i = 0;
        int j = 0;
        int count_read = 0;
        int count_write = 0;
        int count_read_whole = 0;

        while (true) {
            for(; i < length ;) {
                for(int z = 0; z < DES_BLOCK_SIZE; ++z) { // read 8 bytes to indata --> out
                    if(text[i] == '\0') break;
                    input_text[z] = text[i];
                    ++i;
                    ++count_read;
                    if(count_read == DES_BLOCK_SIZE) break;
                }
                break;
            }
            if (count_read < DES_BLOCK_SIZE)
                break;

            // encrypt 8 bytes from input_text to cipher
            DES_ede3_cbc_encrypt(input_text, cipher, count_read, &SchKey1, &SchKey2, &SchKey3,&cblock, DES_ENCRYPT);

            count_read_whole += count_read; // total read bytes

            count_read = 0;

            for(; j < count_read_whole; ++j) { // write encrypted 8 bytes to cipher_out
                cipher_out[j] = cipher[count_write];
                ++count_write;
                if(count_write == DES_BLOCK_SIZE) break;
            }
            j++;

            count_write = 0;
        }

        return cipher_out;
    }
    if(mode == DES_DECRYPT) {
        memset(cblock,0,sizeof(DES_cblock));
        DES_set_odd_parity(&cblock);
        unsigned char *plain_out;
        plain_out = new unsigned char[length];

        int count_read = 0;
        int count_write = 0;
        int count_read_whole = 0;
        int i = 0;
        int j = 0;

        while (true) {
            for(; i < length ;) {
                for(int z = 0; z < DES_BLOCK_SIZE; ++z) { // read 8 bytes to indata --> out
                    if(text[i] == '\0') break;
                    enc_cipher[z] = cipher_out[i];
                    ++i;
                    ++count_read;
                    if(count_read == DES_BLOCK_SIZE) break;
                }
                break;
            }
            if (count_read < DES_BLOCK_SIZE)
                break;

            // Decrypt 8 bytes from enc_cipher to out_buf
            DES_ede3_cbc_encrypt(enc_cipher, out_buf, count_read, &SchKey1, &SchKey2, &SchKey3,&cblock, DES_DECRYPT);

            count_read_whole += count_read; // total read bytes

            count_read = 0;

            for(; j < count_read_whole; ++j) {
                plain_out[j] = out_buf[count_write];
                ++count_write;
                if(count_write == DES_BLOCK_SIZE) break;
            }

            j++;

            count_write = 0;
        }

        return plain_out;
    }
    else {
        LOGE("Choose mode, 1 - encryption | 0 - decryption");
        return nullptr;
    }
}

Encryption/Decryption calls in C++

extern "C"
JNIEXPORT jbyteArray JNICALL
Java_com_example_myapplication_MainActivity_encrypt3des(JNIEnv *env, jobject thiz,
                                                        jbyteArray plain_text) {
    jboolean isCopy;
    int plainText_len = env->GetArrayLength(plain_text);
    jbyte* temp = env->GetByteArrayElements(plain_text,&isCopy);
    const unsigned char* plainText;
    plainText = (unsigned char *) temp;

    unsigned char* cipher_text = start3DES(plainText, plainText_len, DES_ENCRYPT);
    for(int i = 0; i < plainText_len; ++i)
        LOGI("Cipher[%d]: %02X", i, cipher_text[i]);


    jbyteArray ByteArray = env->NewByteArray(plainText_len);
    env->SetByteArrayRegion(ByteArray, 0, plainText_len,
                            reinterpret_cast<const jbyte *>(start3DES(plainText, plainText_len, 1)));

    return ByteArray;

}
extern "C"
JNIEXPORT jbyteArray JNICALL
Java_com_example_myapplication_MainActivity_decrypt3des(JNIEnv *env, jobject thiz,
                                                        jbyteArray enc_text) {
    jboolean isCopy;
    int encText_len = env->GetArrayLength(enc_text);
    jbyte* temp = env->GetByteArrayElements(enc_text, &isCopy);
    const unsigned char* encText;
    encText = (unsigned char *) temp;

    unsigned char* plain = start3DES(encText, encText_len, DES_DECRYPT);
    for(int i = 0; i < encText_len; ++i)
        LOGI("Plain[%d]: %02X", i, plain[i]);

    //LOGI("TDES Dec: %s", plain_text);
    jbyteArray DecryptedByteArray = env->NewByteArray(encText_len);
    env->SetByteArrayRegion(DecryptedByteArray, 0, encText_len, reinterpret_cast<const jbyte *>(start3DES(encText, encText_len, 0)));

    return DecryptedByteArray;
}

Calls from Java

byte[] plainText1 = "c307d1e566991874 ".getBytes();
        byte[] t_des_encrypted = encrypt3des(plainText1);
        decrypt3des(t_des_encrypted);

Tried also ECB 3DES encryption/decryption but it didn't work too.

Botje
  • 26,269
  • 3
  • 31
  • 41
Amir
  • 13
  • 2
  • Your encrypt function calls `start3DES` twice on the same array of bytes, effectively encrypting your input twice. – Botje Aug 15 '23 at 19:54
  • @Botje corrected, that was bad. But the problem still remains. – Amir Aug 16 '23 at 09:36

0 Answers0