3DES解密后在C中将char解码为UTF8
Decoding char to UTF8 in C after 3DES decryption
我需要一些帮助将 C 中的字符解码为其 UTF8 解释。
到目前为止我的代码是这样工作的:
- A
char
初始化为 'password' 70617373776F7264
的十六进制表示
- 然后使用3DES加密
DD201F609E49C0609FABA4C8AAFBB1E5
- 然后使用3DES解密成功
70617373776F72640808080808080808
在printf("decrypted: %s",dec)
语句中,一切正常,显示为decrypted: password
但是当进行字符串比较时,它不匹配。仔细观察 char,我可以看到它显示为 [=17=]1password00000000
(这是由于填充)
有什么方法可以取消填充或解码为 UTF8? something similar to this
使用代码编辑:
#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 = '[=10=]';
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);
}
是不是因为你解密后的字符串没有以NULL结尾?
另外,如果您的 "string comparison" 是
如果(dec == "password")
那是行不通的,试试
如果 (strcmp(dec, "password") == 0)
在 decrypt
函数中,您 return 从局部变量解密的结果,该变量超出了调用者的范围。
将 out[64]
更改为 static
或作为全局,或 malloc
它。
最后您的代码调用 UB 因为您正在 return 获取堆栈区域的地址。
OP 评论请求后编辑
您的密码是
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;
}
此代码将输出数组声明为本地数组,否则已分配堆栈。该变量仅在局部范围内可用:在 decrypt
函数内。
这意味着当函数return调用函数DES_ecb3_do
时一个内存地址可能被破坏。您不应访问该地址。
要解决此问题,您必须使 out
变量在 decrypt
函数范围之外可用,例如,使用以下方法之一:
1) 您将 out
定义为 global
:
unsigned char out[64] = {0};
char *decrypt(char *data)
{
// STUFF
}
2) 在函数中将 out
定义为 static
:
char *decrypt(char *data)
{
static unsigned char out[64] = {0};
// STUFF
}
3) 您将 out
定义为指针,并且 malloc
它:
char *decrypt(char *data)
{
unsigned char *out] = malloc(64);
// STUFF
}
希望已经足够清楚了。
我需要一些帮助将 C 中的字符解码为其 UTF8 解释。
到目前为止我的代码是这样工作的:
- A
char
初始化为 'password'70617373776F7264
的十六进制表示
- 然后使用3DES加密
DD201F609E49C0609FABA4C8AAFBB1E5
- 然后使用3DES解密成功
70617373776F72640808080808080808
在printf("decrypted: %s",dec)
语句中,一切正常,显示为decrypted: password
但是当进行字符串比较时,它不匹配。仔细观察 char,我可以看到它显示为 [=17=]1password00000000
(这是由于填充)
有什么方法可以取消填充或解码为 UTF8? something similar to this
使用代码编辑:
#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 = '[=10=]';
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);
}
是不是因为你解密后的字符串没有以NULL结尾? 另外,如果您的 "string comparison" 是 如果(dec == "password") 那是行不通的,试试 如果 (strcmp(dec, "password") == 0)
在 decrypt
函数中,您 return 从局部变量解密的结果,该变量超出了调用者的范围。
将 out[64]
更改为 static
或作为全局,或 malloc
它。
最后您的代码调用 UB 因为您正在 return 获取堆栈区域的地址。
OP 评论请求后编辑
您的密码是
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;
}
此代码将输出数组声明为本地数组,否则已分配堆栈。该变量仅在局部范围内可用:在 decrypt
函数内。
这意味着当函数return调用函数DES_ecb3_do
时一个内存地址可能被破坏。您不应访问该地址。
要解决此问题,您必须使 out
变量在 decrypt
函数范围之外可用,例如,使用以下方法之一:
1) 您将 out
定义为 global
:
unsigned char out[64] = {0};
char *decrypt(char *data)
{
// STUFF
}
2) 在函数中将 out
定义为 static
:
char *decrypt(char *data)
{
static unsigned char out[64] = {0};
// STUFF
}
3) 您将 out
定义为指针,并且 malloc
它:
char *decrypt(char *data)
{
unsigned char *out] = malloc(64);
// STUFF
}
希望已经足够清楚了。