c - 3DES解密后在C中将char解码为UTF8

标签 c encryption padding 3des

我需要一些帮助将 C 中的字符解码为其 UTF8 解释。

到目前为止,我的代码是这样工作的:

  • char 以“密码”的十六进制表示形式初始化 70617373776F7264
  • 然后使用 3DES DD201F609E49C0609FABA4C8AAFBB1E5
  • 进行加密
  • 然后使用3DES解密成功 70617373776F72640808080808080808

printf("decrypted: %s",dec) 语句中,一切看起来都很好,并显示为 decrypted: password

但是当进行字符串比较时,它不匹配。仔细观察字符,我可以看到它以 \001password\010\010\010\010\010\010\010\010 形式出现(这是由于填充)

有什么方法可以取消填充或解码为 UTF8something 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 = '\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);
}

最佳答案

decrypt 函数中,您从局部变量返回解密结果,这超出了调用者的范围。

out[64] 更改为 static 或全局,或 malloc

最后你的代码调用UB因为你正在返回堆栈区域的地址。

在 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 函数内。

这意味着当函数返回到调用函数 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 定义为一个 poiter 并将其定义为 malloc:

char *decrypt(char *data)
{
   unsigned char *out] = malloc(64);
   // STUFF
}

希望它足够清楚。

关于c - 3DES解密后在C中将char解码为UTF8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32887311/

相关文章:

对函数签名感到困惑

c++ - 多线程不利用多核?

phpseclib 零字节填充

Golang 从 openpgp.js 解密 PGP

c - 免费在哪里使用

c# - 将 C 转换为 C#

c# - 如何解密用 x509 加密的原始 soap 响应

css - 添加边框到填充

ios - - (CGRect) textRectForBounds :(CGRect)bounds not being called

html - 宽度为 100% 的 div,包括边距