VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 1918|回复: 7

[求助] 关于DES加密解密的一个问题

[复制链接]
34_avatar_middle
online_vip 发表于 2016-5-1 14:58:53 | 显示全部楼层 |阅读模式
3驿站币
各位好,最近项目上遇到一个问题:

客户端:(VC)写的DES加密

服务端:(C#)接受客户端传来的HTTP请求的内容,然后进行DES解密。

可是在客户端DES加密过程当中,发现用VC和C#写的加密结果竟然不一样。所以来请教一下各位,是不是我代码写的有问题?

还请大家看看。

C#加密解密代码:

  1. using System;
  2. using System.IO;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Security.Cryptography;

  7. namespace encrypt
  8. {
  9.     class Program
  10.     {

  11.         public static string Encode(string data, string Key) //加密
  12.         {
  13.             byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(Key);
  14.             byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(Key);
  15.             DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
  16.             int i = cryptoProvider.KeySize;
  17.             MemoryStream ms = new MemoryStream();
  18.             CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(byKey, byIV), CryptoStreamMode.Write);
  19.             StreamWriter sw = new StreamWriter(cst);
  20.             sw.Write(data);
  21.             sw.Flush();
  22.             cst.FlushFinalBlock();
  23.             sw.Flush();

  24.             return Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
  25.         }

  26.         public static string Decode(string data, string Key) //解密
  27.         {
  28.             byte[] byKey = System.Text.ASCIIEncoding.ASCII.GetBytes(Key);
  29.             byte[] byIV = System.Text.ASCIIEncoding.ASCII.GetBytes(Key);
  30.             byte[] byEnc;
  31.             try
  32.             {
  33.                 byEnc = Convert.FromBase64String(data);
  34.             }
  35.             catch
  36.             {
  37.                 return null;
  38.             }
  39.             DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
  40.             MemoryStream ms = new MemoryStream(byEnc);
  41.             CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateDecryptor(byKey, byIV), CryptoStreamMode.Read);
  42.             StreamReader sr = new StreamReader(cst);
  43.             return sr.ReadToEnd();
  44.         }
  45.         static void Main(string[] args)
  46.         {
  47.             string ecode;
  48.             string dcode;
  49.             ecode = Encode("Helloworld", "12345678");
  50.             Console.Write(ecode);
  51.             Console.Write("\r\n");


  52.             dcode = Decode(ecode, "12345678");
  53.             Console.Write(dcode);
  54.             Console.Write("\r\n");
  55.         }
  56.     }
  57. }
复制代码


结果:

  1. F:\vc_codes\encrypt\encrypt\bin\Debug>encrypt.exe
  2. LSqu6q9eTDBnoBIJIrNzrw==
  3. Helloworld
复制代码


在C#代码里,我们可以看到它对加密/解密后的值进行了BASE64加密

VC代码:

  1. //////////////////////////////////////////////////////////////////////////
  2. /*
  3.     Provided by 王俊川, Northeastern University (www.neu.edu.cn)
  4.     Email: blackdrn@sohu.com
  5.         This product is free for use.
  6. */
  7. //////////////////////////////////////////////////////////////////////////

  8. #include "memory.h"
  9. #include "WjcDes.h"

  10. //////////////////////////////////////////////////////////////////////////

  11. // initial permutation IP
  12. const static char IP_Table[64] = {
  13.         58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
  14.         62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
  15.         57, 49, 41, 33, 25, 17,  9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
  16.     61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7
  17. };
  18. // final permutation IP^-1
  19. const static char IPR_Table[64] = {
  20.         40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
  21.         38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
  22.     36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
  23.         34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41,  9, 49, 17, 57, 25
  24. };
  25. // expansion operation matrix
  26. static const char E_Table[48] = {
  27.         32,  1,  2,  3,  4,  5,  4,  5,  6,  7,  8,  9,
  28.          8,  9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
  29.         16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
  30.         24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32,  1
  31. };
  32. // 32-bit permutation function P used on the output of the S-boxes
  33. const static char P_Table[32] = {
  34.         16, 7, 20, 21, 29, 12, 28, 17, 1,  15, 23, 26, 5,  18, 31, 10,
  35.         2,  8, 24, 14, 32, 27, 3,  9,  19, 13, 30, 6,  22, 11, 4,  25
  36. };
  37. // permuted choice table (key)
  38. const static char PC1_Table[56] = {
  39.         57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,
  40.         10,  2, 59, 51, 43, 35, 27, 19, 11,  3, 60, 52, 44, 36,
  41.         63, 55, 47, 39, 31, 23, 15,  7, 62, 54, 46, 38, 30, 22,
  42.         14,  6, 61, 53, 45, 37, 29, 21, 13,  5, 28, 20, 12,  4
  43. };
  44. // permuted choice key (table)
  45. const static char PC2_Table[48] = {
  46.         14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,
  47.         23, 19, 12,  4, 26,  8, 16,  7, 27, 20, 13,  2,
  48.         41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
  49.         44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32
  50. };
  51. // number left rotations of pc1
  52. const static char LOOP_Table[16] = {
  53.         1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
  54. };
  55. // The (in)famous S-boxes
  56. const static char S_Box[8][4][16] = {
  57.         // S1
  58.         14,         4,        13,         1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,
  59.          0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,
  60.          4,  1, 14,  8, 13,  6,  2, 11, 15, 12,  9,  7,  3, 10,  5,  0,
  61.     15, 12,  8,  2,  4,  9,  1,  7,  5, 11,  3, 14, 10,  0,  6, 13,
  62.         // S2
  63.     15,  1,  8, 14,  6, 11,  3,  4,  9,  7,  2, 13, 12,  0,  5, 10,
  64.          3, 13,  4,  7, 15,  2,  8, 14, 12,  0,  1, 10,  6,  9, 11,  5,
  65.          0, 14,  7, 11, 10,  4, 13,  1,  5,  8, 12,  6,  9,  3,  2, 15,
  66.     13,  8, 10,  1,  3, 15,  4,  2, 11,  6,  7, 12,  0,  5, 14,  9,       
  67.         // S3
  68.     10,  0,  9, 14,  6,  3, 15,  5,  1, 13, 12,  7, 11,  4,  2,  8,
  69.         13,  7,  0,  9,  3,  4,  6, 10,  2,  8,  5, 14, 12, 11, 15,  1,
  70.         13,  6,  4,  9,  8, 15,  3,  0, 11,  1,  2, 12,  5, 10, 14,  7,
  71.      1, 10, 13,  0,  6,  9,  8,  7,  4, 15, 14,  3, 11,  5,  2, 12,
  72.         // S4
  73.      7, 13, 14,  3,  0,  6,  9, 10,  1,  2,  8,  5, 11, 12,  4, 15,
  74.         13,  8, 11,  5,  6, 15,  0,  3,  4,  7,  2, 12,  1, 10, 14,  9,
  75.         10,  6,  9,  0, 12, 11,  7, 13, 15,  1,  3, 14,  5,  2,  8,  4,
  76.      3, 15,  0,  6, 10,  1, 13,  8,  9,  4,  5, 11, 12,  7,  2, 14,
  77.         // S5
  78.      2, 12,  4,  1,  7, 10, 11,  6,  8,  5,  3, 15, 13,  0, 14,  9,
  79.         14, 11,  2, 12,  4,  7, 13,  1,  5,  0, 15, 10,  3,  9,  8,  6,
  80.          4,  2,  1, 11, 10, 13,  7,  8, 15,  9, 12,  5,  6,  3,  0, 14,
  81.     11,  8, 12,  7,  1, 14,  2, 13,  6, 15,  0,  9, 10,  4,  5,  3,
  82.         // S6
  83.     12,  1, 10, 15,  9,  2,  6,  8,  0, 13,  3,  4, 14,  7,  5, 11,
  84.         10, 15,  4,  2,  7, 12,  9,  5,  6,  1, 13, 14,  0, 11,  3,  8,
  85.          9, 14, 15,  5,  2,  8, 12,  3,  7,  0,  4, 10,  1, 13, 11,  6,
  86.      4,  3,  2, 12,  9,  5, 15, 10, 11, 14,  1,  7,  6,  0,  8, 13,
  87.         // S7
  88.      4, 11,  2, 14, 15,  0,  8, 13,  3, 12,  9,  7,  5, 10,  6,  1,
  89.         13,  0, 11,  7,  4,  9,  1, 10, 14,  3,  5, 12,  2, 15,  8,  6,
  90.          1,  4, 11, 13, 12,  3,  7, 14, 10, 15,  6,  8,  0,  5,  9,  2,
  91.      6, 11, 13,  8,  1,  4, 10,  7,  9,  5,  0, 15, 14,  2,  3, 12,
  92.         // S8
  93.     13,  2,  8,  4,  6, 15, 11,  1, 10,  9,  3, 14,  5,  0, 12,  7,
  94.          1, 15, 13,  8, 10,  3,  7,  4, 12,  5,  6, 11,  0, 14,  9,  2,
  95.          7, 11,  4,  1,  9, 12, 14,  2,  0,  6, 10, 13, 15,  3,  5,  8,
  96.      2,  1, 14,  7,  4, 10,  8, 13, 15, 12,  9,  0,  3,  5,  6, 11
  97. };

  98. //////////////////////////////////////////////////////////////////////////

  99. typedef bool    (*PSubKey)[16][48];

  100. //////////////////////////////////////////////////////////////////////////

  101. static void DES(char Out[8], char In[8], const PSubKey pSubKey, bool Type);//标准DES加/解密
  102. static void SetKey(const char* Key, int len);// 设置密钥
  103. static void SetSubKey(PSubKey pSubKey, const char Key[8]);// 设置子密钥
  104. static void F_func(bool In[32], const bool Ki[48]);// f 函数
  105. static void S_func(bool Out[32], const bool In[48]);// S 盒代替
  106. static void Transform(bool *Out, bool *In, const char *Table, int len);// 变换
  107. static void Xor(bool *InA, const bool *InB, int len);// 异或
  108. static void RotateL(bool *In, int len, int loop);// 循环左移
  109. static void ByteToBit(bool *Out, const char *In, int bits);// 字节组转换成位组
  110. static void BitToByte(char *Out, const bool *In, int bits);// 位组转换成字节组

  111. //////////////////////////////////////////////////////////////////////////

  112. static bool SubKey[2][16][48];// 16圈子密钥
  113. static bool Is3DES;// 3次DES标志
  114. static char Tmp[256], deskey[16];

  115. //////////////////////////////////////////////////////////////////////////

  116. //////////////////////////////////////////////////////////////////////////
  117. // Code starts from Line 130
  118. //////////////////////////////////////////////////////////////////////////
  119. bool Des_Go(char *Out, char *In, long datalen, const char *Key, int keylen, bool Type)
  120. {
  121.     if( !( Out && In && Key && (datalen=(datalen+7)&0xfffffff8) ) )
  122.                 return false;
  123.         SetKey(Key, keylen);
  124.         if( !Is3DES ) {   // 1次DES
  125.                 for(long i=0,j=datalen>>3; i<j; ++i,Out+=8,In+=8)
  126.                         DES(Out, In, &SubKey[0], Type);
  127.         } else{   // 3次DES 加密:加(key0)-解(key1)-加(key0) 解密::解(key0)-加(key1)-解(key0)
  128.                 for(long i=0,j=datalen>>3; i<j; ++i,Out+=8,In+=8) {
  129.                         DES(Out, In,  &SubKey[0], Type);
  130.                         DES(Out, Out, &SubKey[1], !Type);
  131.                         DES(Out, Out, &SubKey[0], Type);
  132.                 }
  133.         }
  134.         return true;
  135. }
  136. void SetKey(const char* Key, int len)
  137. {
  138.         memset(deskey, 0, 16);
  139.         memcpy(deskey, Key, len>16?16:len);
  140.         SetSubKey(&SubKey[0], &deskey[0]);
  141.         Is3DES = len>8 ? (SetSubKey(&SubKey[1], &deskey[8]), true) : false;
  142. }
  143. void DES(char Out[8], char In[8], const PSubKey pSubKey, bool Type)
  144. {
  145.     static bool M[64], tmp[32], *Li=&M[0], *Ri=&M[32];
  146.     ByteToBit(M, In, 64);
  147.     Transform(M, M, IP_Table, 64);
  148.     if( Type == ENCRYPT ){
  149.         for(int i=0; i<16; ++i) {
  150.             memcpy(tmp, Ri, 32);
  151.             F_func(Ri, (*pSubKey)[i]);
  152.             Xor(Ri, Li, 32);
  153.             memcpy(Li, tmp, 32);
  154.         }
  155.     }else{
  156.         for(int i=15; i>=0; --i) {
  157.             memcpy(tmp, Li, 32);
  158.             F_func(Li, (*pSubKey)[i]);
  159.             Xor(Li, Ri, 32);
  160.             memcpy(Ri, tmp, 32);
  161.         }
  162.         }
  163.     Transform(M, M, IPR_Table, 64);
  164.     BitToByte(Out, M, 64);
  165. }
  166. void SetSubKey(PSubKey pSubKey, const char Key[8])
  167. {
  168.     static bool K[64], *KL=&K[0], *KR=&K[28];
  169.     ByteToBit(K, Key, 64);
  170.     Transform(K, K, PC1_Table, 56);
  171.     for(int i=0; i<16; ++i) {
  172.         RotateL(KL, 28, LOOP_Table[i]);
  173.         RotateL(KR, 28, LOOP_Table[i]);
  174.         Transform((*pSubKey)[i], K, PC2_Table, 48);
  175.     }
  176. }
  177. void F_func(bool In[32], const bool Ki[48])
  178. {
  179.     static bool MR[48];
  180.     Transform(MR, In, E_Table, 48);
  181.     Xor(MR, Ki, 48);
  182.     S_func(In, MR);
  183.     Transform(In, In, P_Table, 32);
  184. }
  185. void S_func(bool Out[32], const bool In[48])
  186. {
  187.     for(char i=0,j,k; i<8; ++i,In+=6,Out+=4) {
  188.         j = (In[0]<<1) + In[5];
  189.         k = (In[1]<<3) + (In[2]<<2) + (In[3]<<1) + In[4];
  190.                 ByteToBit(Out, &S_Box[i][j][k], 4);
  191.     }
  192. }
  193. void Transform(bool *Out, bool *In, const char *Table, int len)
  194. {
  195.     for(int i=0; i<len; ++i)
  196.         Tmp[i] = In[ Table[i]-1 ];
  197.     memcpy(Out, Tmp, len);
  198. }
  199. void Xor(bool *InA, const bool *InB, int len)
  200. {
  201.     for(int i=0; i<len; ++i)
  202.         InA[i] ^= InB[i];
  203. }
  204. void RotateL(bool *In, int len, int loop)
  205. {
  206.     memcpy(Tmp, In, loop);
  207.     memcpy(In, In+loop, len-loop);
  208.     memcpy(In+len-loop, Tmp, loop);
  209. }
  210. void ByteToBit(bool *Out, const char *In, int bits)
  211. {
  212.     for(int i=0; i<bits; ++i)
  213.         Out[i] = (In[i>>3]>>(i&7)) & 1;
  214. }
  215. void BitToByte(char *Out, const bool *In, int bits)
  216. {
  217.     memset(Out, 0, bits>>3);
  218.     for(int i=0; i<bits; ++i)
  219.         Out[i>>3] |= In[i]<<(i&7);
  220. }
  221. //////////////////////////////////////////////////////////////////////////
  222. // Code ends at Line 231
  223. //////////////////////////////////////////////////////////////////////////
复制代码


  1. #include "WjcDes.h"
  2. #include "stdio.h"
  3. #include "string.h"
  4. #include "memory.h"


  5. void main()
  6. {
  7.         char key[]={1,2,3,4,5,6,7,8},buf[255];
  8.         char str[]="Helloworld";

  9. //        char str[]="353163";
  10.         memset(buf, 0, sizeof(buf));
  11.         strcpy(buf, str);
  12.         puts("\nBefore encrypting");
  13.         puts(buf);

  14.         Des_Go(buf, buf, sizeof(str), key, sizeof(key), ENCRYPT);
  15.         puts("\nAfter encrypting");
  16.         puts(buf);

  17.         if (buf[strlen(buf) -1] == '\r')
  18.         {
  19.                 buf[strlen(buf) -1] = '\0';
  20.         }

  21.         if (buf[strlen(buf) -1] == '\n')
  22.         {
  23.                 buf[strlen(buf) -1] = '\0';
  24.         }



  25.         FILE* fp = fopen("des.txt","a+");
  26.         fwrite(buf,strlen(buf),1,fp);
  27.         fclose(fp);


  28.         FILE* ffp = fopen("des.txt","rb");  //读取的保存加密后的数据
  29.         char buffer[1024] = {0};
  30.         char *szOutput = new char [100*2];
  31.         while (!feof(fp))
  32.         {
  33.                 fgets(buffer,sizeof(buffer),ffp);
  34.         }

  35.         fclose(ffp);

  36.         for (int i = 0;i<strlen(buffer);i++)
  37.         {
  38.                 sprintf(szOutput + i * 2, "%.2x", (unsigned char)buffer[i]); //读取出来数据进行16进制转换
  39.         }

  40.         printf("szoutbuf = %s\r\n",szOutput);

  41. }
复制代码

  1. F:\vc_codes\wcdes\Debug>wcdes.exe

  2. Before encrypting
  3. Helloworld

  4. After encrypting
  5. 宿
  6. 窔忇d鋢?叅
  7. szoutbuf = b79a8fe00164e478c62685a41f  这里是转换成16进制的数据

复制代码


如果按照C#里的代码逻辑,我这儿还应该换成BASE64,BASE64=Yjc5YThmZTAwMTY0ZTQ3OGM2MjY4NWE0MWYlMjAlMjA=

很明显,和C# 加密后的结果根本不一样,请问到底是什么原因呢?

主要是想写一个通用的加密解密,客户端和服务端因为不是用一个语言写的,所以现在项目需求就是这样:VC DES加密发到服务端,然后服务断是C#写的,接收到的数据进行DES解密。

可是现在不知道为什么,连加密后的结果都不一样,还请各位看看到底是怎么回事。

在VC DES加密这边,我把数据加密后,在换成了16进制,最后在BASE64加密,请问流程对吗?是这样吗? 为什么结果会不一样呢。





上一篇:VC6.0 MFC AppWizard生成的工程,菜单项的响应函数在什么地方?
下一篇:数据转换问题
74_avatar_middle
在线会员 发表于 2016-5-2 09:12:38 | 显示全部楼层
孤不能忍受 c#代碼(好吧除了c/c++ 彙編 go 沒多少語言是孤能忍受的) 所以孤無法看你給出的 c#代碼
然 在對稱加密時 新人可能會出現 以下一些問題 你看下 你是否注意過

1 加密/解密是否使用了 相同 工作模式 ECB CBC CFB         OFB         CTR
   如果你不知道 工作模式是 什麼 很可能問題出在此 自己google下
   而且 你使用了 不同的語言 不同語言自帶的庫/第三方庫 默認的 工作模式 往往不同 所以在本語言/庫 下加密解密正確 和其它組件 交互卻得不到正確數據

2  數據填充方式 是否相同
   和工作模式類似 如果不清楚 自己 google

评分

参与人数 1威望 +2 +3 热心值 +3 收起 理由
51_avatar_small Syc + 2 + 3 + 3 赞一个!

查看全部评分

51_avatar_middle
online_admins 发表于 2016-5-2 22:23:00 | 显示全部楼层
这么长的代码还真不知道从哪里开始看起,不过既然你现在也不确定到底是C++的代码有问题还是C#的代码有问题,那么我的建议就是找个现成的第三方软件直接使用DES进行加解密,之后拿结果跟你代码的加解密结果做对比,看看到底是C++的正确还是C#的正确?
34_avatar_middle
ico_lz  楼主| 发表于 2016-5-3 03:08:11 | 显示全部楼层
Syc 发表于 2016-5-2 22:23
这么长的代码还真不知道从哪里开始看起,不过既然你现在也不确定到底是C++的代码有问题还是C#的代码有问题 ...

VC写的只能在VC那儿解密。C#写的只能在C#那儿解密。 我都是网上找来的代码,可能是标准不一样吧。
51_avatar_middle
online_admins 发表于 2016-5-3 11:47:59 | 显示全部楼层
保证不打死你 发表于 2016-5-3 03:08
VC写的只能在VC那儿解密。C#写的只能在C#那儿解密。 我都是网上找来的代码,可能是标准不一样吧。

只要秘钥一样,加密结果应该是一样的
74_avatar_middle
在线会员 发表于 2016-5-9 11:27:36 | 显示全部楼层
Syc 发表于 2016-5-3 11:47
只要秘钥一样,加密结果应该是一样的

對稱加密中 除了密鑰一樣
還要 工作模式 和 數據填充方式一樣 加解密結果才能一樣
11_avatar_middle
online_vip 发表于 2016-5-11 11:37:10 | 显示全部楼层
师兄  新手呀。。我发现des  加密好多种结构    问道的游戏des 加密算出来的结果没有一个跟别人是相同的   
40_avatar_middle
在线会员 发表于 2016-5-13 08:57:25 | 显示全部楼层
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2019-3-20 16:10

Powered by Discuz! X3.4

© 2009-2019 cctry.com

快速回复 返回顶部 返回列表