昨天做项目的时候,遇到了c++通讯发送加密数据c#解密出错问题。

因为有很多选项,特地做了个对比,研究了其中的一些参数

DES

要注意的项目:

1.密钥 Key、IV

两个密钥都是8字节

2.模式 ECB、CBC

在ECB模式下,只用key;在CBC模式下,同时使用key和IV

3.字节填充模式  非8倍数字节数、8倍数字节数

C# DES
{
    //输入 
    byte[] INPUT_buffer____ = { 0x31, };

    //ECB
    byte[] ECB_PKCS7_____ = { 0xD6, 0x98, 0x32, 0xA0, 0x62, 0x9A, 0xB7, 0x0F, };
    byte[] ECB_Zeros_____ = { 0xB6, 0x61, 0x3E, 0xE6, 0x93, 0x8B, 0x45, 0x71, };// 填充Zero√
    byte[] ECB_ANSIX923__ = { 0x7C, 0xB0, 0xEE, 0xE6, 0xD1, 0x3C, 0xC7, 0x88, };
    byte[] ECB_ISO10126__ = { 0x0A, 0x22, 0x65, 0xE4, 0x2E, 0xB3, 0xBC, 0x34, };

    //CBC
    byte[] CBC_PKCS7_____ = { 0x3C, 0x77, 0x8E, 0xD4, 0x82, 0xA6, 0x66, 0x36, };
    byte[] CBC_Zeros_____ = { 0x40, 0x9D, 0xA7, 0xE5, 0x0D, 0xDF, 0x61, 0x7E, };// 填充Zero√
    byte[] CBC_ANSIX923__ = { 0x41, 0x91, 0x0C, 0xCE, 0xC4, 0x41, 0x77, 0xFF, };
    byte[] CBC_ISO10126__ = { 0x5C, 0x9C, 0xA9, 0xD6, 0x65, 0x23, 0x5E, 0x39, };
}

C# DES
{
    //输入 
    byte[] INPUT_buffer____ = { 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, };

    //ECB
    byte[] ECB_PKCS7_____ = { 0x74, 0xA5, 0x81, 0x53, 0x4A, 0x4B, 0xF8, 0xB1, 0x89, 0xF4, 0xD1, 0xBA, 0x96, 0x97, 0x9A, 0xD0, };
    byte[] ECB_Zeros_____ = { 0x74, 0xA5, 0x81, 0x53, 0x4A, 0x4B, 0xF8, 0xB1, };// 填充Zero√
    byte[] ECB_ANSIX923__ = { 0x74, 0xA5, 0x81, 0x53, 0x4A, 0x4B, 0xF8, 0xB1, 0x24, 0xC8, 0x74, 0xB9, 0x6D, 0x5C, 0x9E, 0x13, };
    byte[] ECB_ISO10126__ = { 0x74, 0xA5, 0x81, 0x53, 0x4A, 0x4B, 0xF8, 0xB1, 0xAC, 0xB2, 0x70, 0x9C, 0xDC, 0xB5, 0x2C, 0x03, };

    //CBC
    byte[] CBC_PKCS7_____ = { 0x6B, 0x0E, 0xC8, 0x18, 0x33, 0xE5, 0xE6, 0xA7, 0x70, 0xF9, 0x31, 0x8D, 0xDF, 0x6C, 0x6A, 0x86, };
    byte[] CBC_Zeros_____ = { 0x6B, 0x0E, 0xC8, 0x18, 0x33, 0xE5, 0xE6, 0xA7, };// 填充Zero√
    byte[] CBC_ANSIX923__ = { 0x6B, 0x0E, 0xC8, 0x18, 0x33, 0xE5, 0xE6, 0xA7, 0x28, 0xA0, 0xBC, 0x4A, 0x5A, 0x28, 0x41, 0xB8, };
    byte[] CBC_ISO10126__ = { 0x6B, 0x0E, 0xC8, 0x18, 0x33, 0xE5, 0xE6, 0xA7, 0xD5, 0xF9, 0x47, 0xDD, 0xF3, 0xCE, 0x7D, 0xC2, };
}

2017-10-19 22:59:33,455 - 461560 [DEBUG] : ECB : PAD_ISO_1
2017-10-19 22:59:33,456 - 461560 [DEBUG] : B6613EE6938B45710000000000000000
2017-10-19 22:59:33,457 - 461560 [DEBUG] : ECB : PAD_ISO_2
2017-10-19 22:59:33,457 - 461560 [DEBUG] : B6613EE6938B45710000000000000000
2017-10-19 22:59:33,458 - 461560 [DEBUG] : ECB : PAD_PKCS_7
2017-10-19 22:59:33,458 - 461560 [DEBUG] : B6613EE6938B45710000000000000000 // 填充Zero√


2017-10-19 22:59:33,459 - 461560 [DEBUG] : CBC : PAD_ISO_1
2017-10-19 22:59:33,460 - 461560 [DEBUG] : 409DA7E50DDF617E0000000000000000
2017-10-19 22:59:33,460 - 461560 [DEBUG] : CBC : PAD_ISO_2
2017-10-19 22:59:33,461 - 461560 [DEBUG] : 409DA7E50DDF617E0000000000000000
2017-10-19 22:59:33,462 - 461560 [DEBUG] : CBC : PAD_PKCS_7
2017-10-19 22:59:33,462 - 461560 [DEBUG] : 409DA7E50DDF617E0000000000000000 // 填充Zero√



2017-10-19 23:01:30,977 - 464436 [DEBUG] : ECB : PAD_ISO_1
2017-10-19 23:01:30,979 - 464436 [DEBUG] : 74A581534A4BF8B10000000000000000
2017-10-19 23:01:30,980 - 464436 [DEBUG] : ECB : PAD_ISO_2
2017-10-19 23:01:30,981 - 464436 [DEBUG] : 74A581534A4BF8B10000000000000000
2017-10-19 23:01:30,982 - 464436 [DEBUG] : ECB : PAD_PKCS_7
2017-10-19 23:01:30,983 - 464436 [DEBUG] : 74A581534A4BF8B10000000000000000 // 填充Zero√

2017-10-19 23:01:30,988 - 464436 [DEBUG] : CBC : PAD_ISO_1
2017-10-19 23:01:30,989 - 464436 [DEBUG] : 6B0EC81833E5E6A70000000000000000
2017-10-19 23:01:30,990 - 464436 [DEBUG] : CBC : PAD_ISO_2
2017-10-19 23:01:30,990 - 464436 [DEBUG] : 6B0EC81833E5E6A70000000000000000
2017-10-19 23:01:30,991 - 464436 [DEBUG] : CBC : PAD_PKCS_7
2017-10-19 23:01:30,992 - 464436 [DEBUG] : 6B0EC81833E5E6A70000000000000000  // 填充Zero√

长度不足应该补充 00 ,并且只有不满足8倍数字节的时候才补充字节

不同的填充模式,对于输出的结果最后一组数据会有很大不同。

譬如:

金融DES:在末尾填充“8000...”

PKCS #7: 填充字符串由一个字节序列组成,每个字节填充该字节序列的长度。
Zeros :填充字符串由设置为零的字节组成。
ANSIX923: 填充字符串由一个字节序列组成,此字节序列的最后一个字节填充字节序列的长度,其余字节均填充数字零。
ISO10126: 填充字符串由一个字节序列组成,此字节序列的最后一个字节填充字节序列的长度,其余字节填充随机数据。

 

代码中C++库,对于其他填充模式支持不好,默认设置为 PAD_PKCS_7,并表现出跟C# Zero填充一样的效果

下面贴出代码示例

c#代码

        private byte[] Encrypt(byte[] inputByteArray, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();

            //建立加密对象的密钥和偏移量  
            //原文使用ASCIIEncoding.ASCII方法的GetBytes方法  
            //使得输入密码必须输入英文文本  
            des.Mode = CipherMode.CBC;
            des.Padding = PaddingMode.Zeros;
            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
            des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            //Write  the  byte  array  into  the  crypto  stream  
            //(It  will  end  up  in  the  memory  stream)  
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();

            //Get  the  data  back  from  the  memory  stream
            byte[] result = ms.ToArray();
            return result;
        }

        //解密方法  
        private byte[] Decrypt(byte[] inputByteArray, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();

            //建立加密对象的密钥和偏移量,此值重要,不能修改  
            des.Mode = CipherMode.CBC;
            des.Padding = PaddingMode.Zeros;
            des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
            des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            //Flush  the  data  through  the  crypto  stream  into  the  memory  stream  
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();

            //Get  the  data  back  from  the  memory  stream
            byte[] result = ms.ToArray();
            return result;
        }
View Code

相关文章:

  • 2022-01-06
  • 2022-12-23
  • 2022-12-23
  • 2021-10-24
  • 2021-12-29
  • 2022-12-23
猜你喜欢
  • 2021-06-19
  • 2021-11-30
  • 2022-12-23
  • 2021-10-05
  • 2021-09-06
相关资源
相似解决方案