Java和.NET使用DES对称加密的区别

发表于:2012-5-22 09:32

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Lawson    来源:51Testing软件测试网采编

  Java和.NET的系统类库里都有封装DES对称加密的实现方式,但是对外暴露的接口却各不相同,甚至有时会让自己难以解决其中的问题,比如Java加密后的结果在.NET中解密不出来等,由于最近项目有跨Java和.NET的加解密,经过我的分析调试,终于让它们可以互相加密解密了。

  DES加密

  DES是一种对称加密(Data Encryption Standard)算法,以前我写过一篇文章:.NET中加密解密相关知识,有过简单描述。

  DES算法一般有两个关键点,第一个是加密算法,第二个是数据补位。

  加密算法常见的有ECB模式和CBC模式:

  ECB模式:电子密本方式,这是JAVA封装的DES算法的默认模式,就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,则补足8个字节(注意:这里就涉及到数据补位了)进行计算,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。

  CBC模式:密文分组链接方式,这是.NET封装的DES算法的默认模式,它比较麻烦,加密步骤如下:

  1、首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,就涉及到数据补位了)

  2、第一组数据D1与向量I异或后的结果进行DES加密得到第一组密文C1(注意:这里有向量I的说法,ECB模式下没有使用向量I)

  3、第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2

  4、之后的数据以此类推,得到Cn

  5、按顺序连为C1C2C3......Cn即为加密结果。

  数据补位一般有NoPadding和PKCS7Padding(JAVA中是PKCS5Padding)填充方式,PKCS7Padding和PKCS5Padding实际只是协议不一样,根据相关资料说明:PKCS5Padding明确定义了加密块是8字节,PKCS7Padding加密快可以是1-255之间。但是封装的DES算法默认都是8字节,所以可以认为他们一样。数据补位实际是在数据不满8字节的倍数,才补充到8字节的倍数的填充过程。

  NoPadding填充方式:算法本身不填充,比如.NET的padding提供了有None,Zeros方式,分别为不填充和填充0的方式。

  PKCS7Padding(PKCS5Padding)填充方式:为.NET和JAVA的默认填充方式,对加密数据字节长度对8取余为r,如r大于0,则补8-r个字节,字节为8-r的值;如果r等于0,则补8个字节8。比如:

  加密字符串为为AAA,则补位为AAA55555;加密字符串为BBBBBB,则补位为BBBBBB22;加密字符串为CCCCCCCC,则补位为CCCCCCCC88888888。

  .NET中的DES加密

  对于.NET,框架在System.Security.Cryptography命名空间下提供了DESCryptoServiceProvider作为System.Security.Cryptography.DES加密解密的包装接口,它提供了如下的4个方法:

  1. public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)  
  2. public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)  
  3. public override void GenerateIV()  
  4. public override void GenerateKey()

  从.NET类库封装情况,加解密需要传入一个Key和IV向量。而且Key必须为8字节的数据,否则会直接抛异常出来,当使用ECB模式下,不管传入什么IV向量,加密结果都一样。示例代码如下:

  1. public static string EncryptWithJava(string key, string str)  
  2. {  
  3.     if (key.Length < 8 || string.IsNullOrEmpty(str))  
  4.     {  
  5.         throw new Exception("加密key小于8或者加密字符串为空!");  
  6.     }  
  7.     byte[] bKey = Encoding.UTF8.GetBytes(key.Substring(08));  
  8.     byte[] bIV = IV;  
  9.     byte[] bStr = Encoding.UTF8.GetBytes(str);  
  10.     try 
  11.     {  
  12.         DESCryptoServiceProvider desc = new DESCryptoServiceProvider();  
  13.         desc.Padding = PaddingMode.PKCS7;//补位 
  14.         desc.Mode = CipherMode.ECB;//CipherMode.CBC 
  15.         using (MemoryStream mStream = new MemoryStream())  
  16.         {  
  17.             using (CryptoStream cStream = new CryptoStream(mStream, desc.CreateEncryptor(bKey, bIV), CryptoStreamMode.Write))  
  18.             {  
  19.                 cStream.Write(bStr, 0, bStr.Length);  
  20.                 cStream.FlushFinalBlock();  
  21.                 StringBuilder ret = new StringBuilder();  
  22.                 byte[] res = mStream.ToArray();  
  23.                 foreach (byte b in res)  
  24.                 {  
  25.                     ret.AppendFormat("{0:x2}", b);  
  26.                 }  
  27.                 return ret.ToString();  
  28.             }  
  29.         }  
  30.     }  
  31.     catch 
  32.     {  
  33.         return string.Empty;  
  34.     }  
  35. }

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号