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.