I need some help decoding a char in C to its UTF8 interpretation.
My code so far works this way:
char
is initialised with hexadecimal representation of 'password' 70617373776F7264
DD201F609E49C0609FABA4C8AAFBB1E5
70617373776F72640808080808080808
In theprintf("decrypted: %s",dec)
statement, all looks fine and it is displayed as decrypted: password
However when doing a string compare, it does not match. Looking closely at the char, I can see that it comes out as \001password\010\010\010\010\010\010\010\010
(this is due to the padding)
Is there any way to either un-pad or to decode to UTF8? something similar to this
Edit with code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/des.h>
#include <openssl/rand.h>
#include <ldap.h>
#include "k.h"
#include "hex.h"
#define ULONG unsigned long
#define INT unsigned int
char *encrypt(char *data)
{
int i = 0;
int len = 0;
int nlen = 0;
char *key1 = "1313232323231313";
char *key2 = "6789678967896789";
char *key3 = "1313232323231313";
/* Padding */
char ch = '\0';
unsigned char out[64] = {0};
unsigned char src[64] = {0};
unsigned char *ptr = NULL;
unsigned char block[8] = {0};
DES_key_schedule ks1, ks2, ks3;
/* set password table */
ptr = hex2bin(key1, strlen(key1), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks1);
ptr = hex2bin(key2, strlen(key2), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks2);
ptr = hex2bin(key3, strlen(key3), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks3);
ptr = hex2bin(data, strlen(data), &nlen);
memcpy(src, ptr, nlen);
free(ptr);
len = (nlen / 8 + (nlen % 8 ? 1: 0)) * 8;
ch = 8 - nlen % 8;
memset(src + nlen, ch, (8 - nlen % 8) % 8);
printf("Raw data: ");
for (i = 0; i < len; i++) {
printf("%02X", *(src + i));
}
printf("\n");
for (i = 0; i < len; i += 8) {
DES_ecb3_encrypt((C_Block *)(src + i), (C_Block *)(out + i), &ks1, &ks2, &ks3, DES_ENCRYPT);
}
printf("Encrypted: ");
for (i = 0; i < len; i++) {
printf("%02X" , *(out + i));
}
printf("\n");
return out;
}
char *decrypt(char *data)
{
int i = 0;
int len = 0;
int nlen = 0;
char *key1 = "1313232323231313";
char *key2 = "6789678967896789";
char *key3 = "1313232323231313";
/* Padding */
int ch = 0;
unsigned char out[64] = {0};
unsigned char src[64] = {0};
unsigned char *ptr = NULL;
unsigned char block[8] = {0};
DES_key_schedule ks1, ks2, ks3;
/* set password table */
ptr = hex2bin(key1, strlen(key1), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks1);
ptr = hex2bin(key2, strlen(key2), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks2);
ptr = hex2bin(key3, strlen(key3), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks3);
ptr = hex2bin(data, strlen(data), &nlen);
memcpy(src, ptr, nlen);
free(ptr);
len = (nlen / 8 + (nlen % 8 ? 1: 0)) * 8;
ch = 8 - nlen % 8;
memset(src + nlen, ch, (8 - nlen % 8) % 8);
printf("Raw data: ");
for (i = 0; i < len; i++) {
printf("%02X", *(src + i));
}
printf("\n");
for (i = 0; i < len; i += 8) {
DES_ecb3_encrypt((C_Block *)(src + i), (C_Block *)(out + i), &ks1, &ks2, &ks3, DES_DECRYPT);
}
printf("Decrypted: ");
for (i = 0; i < len; i++) {
printf("%02X", *(out + i));
}
printf("\n");
return out;
}
K DES_ecb3_do(K user, K pass,K fl )
{
int res = 0;
int flag = fl->i;
char *usn = user->s;
char *enc = pass->s;
char *decr = "";
char dec[32];
if(flag==1)
{
decr = encrypt(enc);
strcat(dec,decr);
}
else if(flag==0)
{
decr = decrypt(enc);
strcat(dec,decr);
}
int ret;
ret = strcmp(dec, "password");
if(ret==0)
{
printf("they match");
}
else
{
printf("they don't match\n");
return (K) 0;
}
printf("decrypted pass is:%s\n",dec);
return ks(dec);
}
In decrypt
function you return the result of decryption from a local variable, that is out of scope in the caller.
Change out[64]
to static
or as global, or malloc
it.
Finally your code invoke UB because of you are returning an address of stack area.
EDIT after OP comment request
Your code is
char *decrypt(char *data)
{
int i = 0;
int len = 0;
int nlen = 0;
char *key1 = "1313232323231313";
char *key2 = "6789678967896789";
char *key3 = "1313232323231313";
/* Padding */
int ch = 0;
unsigned char out[64] = {0};
unsigned char src[64] = {0};
// stuff....
return out;
}
This code is declaring out array as local, otherwise stack allocated. That the variable is available only in local scope: inside decrypt
function.
This means that when the function return to the caller function DES_ecb3_do
a memory address that could be corrupted. You should not access that address.
To solve the problem you must make out
variable available out of decrypt
function scope using, for example, one of the following:
1) you define the out
as global
:
unsigned char out[64] = {0};
char *decrypt(char *data)
{
// STUFF
}
2) You define out
as static
inside your function:
char *decrypt(char *data)
{
static unsigned char out[64] = {0};
// STUFF
}
3) You define out
as a poiter and malloc
it:
char *decrypt(char *data)
{
unsigned char *out] = malloc(64);
// STUFF
}
Hope it is clear enough.