用 Java 解密 C# 加密的数据(DES)
2009-11-05 11:40
701 查看
用 Java 解密 C# 加密的数据(DES)
[原文地址:http://yidinghe.cnblogs.com/articles/449212.html]今天碰上一件令我头大的事情。我们的系统要和一个外部系统进行通讯,传输方式是采用 DES 算法对消息进行加密,再用 BASE64 编码。不过对方系统是用 C# 写的。平台不一样,于是我和对面的老兄先测试一下加密解密。这一测试问题就来了。两边采用同样的密钥,对同一个字符串加密出来的结果不一样。怎么办呢?我先把他那边的代码要过来了,他是这样写的(C#):
public static string Encrypt(string message, string key)
{
DES des = new DESCryptoServiceProvider();
des.Key = Encoding.UTF8.GetBytes(key);
des.IV = Encoding.UTF8.GetBytes(key);
byte[] bytes = Encoding.UTF8.GetBytes(message);
byte[] resultBytes = des.CreateEncryptor().TransformFinalBlock(bytes, 0, bytes.Length);
return Convert.ToBase64String(resultBytes);
}
而我这边呢,是用 Java 这样写的(仅仅加密到字节串,BASE64 编码是在另一个类里):
public static byte[] desEncrypt(String message, String key) throws Exception {
Cipher cipher = Cipher.getInstance("DES");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(message.getBytes("UTF-8"));
}
两边一对比我就奇怪了,他那边怎么有个 IV (initialization vector)?我打开JDK文档一看Cipher类,竟然也有一个getIV()方法。看来这 IV 大有来头。于是在JDK文档里面到处找IV,找到了一个叫“IvParameterSpec“的类,莫非就是它?它实现的是 AlgorithmParameterSpec 接口,而Cipher.init()中就有一个 AlgorithmParameterSpec 类型的参数。那么看来就是它了。于是参考了IvParameterSpec的构造函数后,我这样把它加进去:
public static byte[] desEncrypt(String message, String key) throws Exception {
Cipher cipher = Cipher.getInstance("DES");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv = new IvParameterSpec(key.getBytes("UTF-8"));
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
return cipher.doFinal(message.getBytes("UTF-8"));
}
这下行了吧,结果一运行报异常:
java.security.InvalidAlgorithmParameterException: ECB mode cannot use IV
这又是什么? “ECB”? 还是找吧,在JDK文档中找到了这么几句鬼东西:
the SunJCE provider uses ECB as the default mode, and PKCS5Padding as the default padding scheme for DES, DES-EDE and Blowfish ciphers. This means that in the case of the SunJCE provider,
Cipher c1 = Cipher.getInstance("DES/ECB/PKCS5Padding");
and
Cipher c1 = Cipher.getInstance("DES");
are equivalent statements.
哦,问题就出在方法里的第一行。那么不准用 ECB,该用什么呢?在该文往下找,找到了这么几项:
The following names can be specified as the mode component in a transformation when requesting an instance of
Cipher:
NONE: No mode.
CBC: Cipher Block Chaining Mode, as defined in FIPS PUB 81.
CFB: Cipher Feedback Mode, as defined in FIPS PUB 81.
ECB: Electronic Codebook Mode, as defined in: The National Institute of Standards and Technology (NIST) Federal Information Processing Standard (FIPS) PUB 81, "DES Modes of Operation," U.S. Department of Commerce, Dec 1980.
OFB: Output Feedback Mode, as defined in FIPS PUB 81.
PCBC: Propagating Cipher Block Chaining, as defined by Kerberos V4.
我这样都换着试一下就行了。哎,运气不错,拿着第一个 CBC 试一下就成功了,加密后的字符串也“正确”了。
我那个方法就变成这样:
public static byte[] desEncrypt(String message, String key) throws Exception {
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
IvParameterSpec iv= new IvParameterSpec(key.getBytes("UTF-8"));
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
return cipher.doFinal(message.getBytes("UTF-8"));
}
这样,解决了这个 ECB 之后,Java 和 .net 平台的两个应用终于能够相互加密和解密数据了。什么?文不对题?加密都写出来了,解密还不简单?自己看着办吧。
[原文地址:http://yidinghe.cnblogs.com/articles/449212.html]
相关文章推荐
- 用 Java 解密 C# 加密的数据(DES)(转)
- 【转】用 Java 解密 C# 加密的数据(DES)
- C#解密(DES)Java的加密结果
- Java加密和C#解密=>DES方法
- Java和C#交叉加密解密方法(DES)
- C# 與JAVA 共用的DES 加密解密方法
- Java与C#交互DES算法加密解密数据
- DES 加密解密C#&JAVA
- 加密解密算法java实现(2)—DES
- C# 的 DES 加密解密
- C# 加密解密(DES,3DES,MD5,Base64) 类
- Java加密解密DESUtil、TripleDESUtil(未测试)
- Aes使用Java加密C#解密
- C# Java间进行RSA加密解密交互(三)
- Android 3DES加密解密(JAVA和C#)
- SELECT INTO和INSERT INTO SELECT的区别 类似aaa?a=1&b=2&c=3&d=4,如何将问号以后的数据变为键值对 C# 获取一定区间的随即数 0、1两个值除随机数以外的取值方法(0、1两个值被取值的概率相等) C# MD5 加密,解密 C#中DataTable删除多条数据
- C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法
- Java 加密解密之对称加密算法DES
- java des 加密/解密
- Java 加解密类的功能用法介绍及实际项目中数据加密解密的解决办法