Java与Delphi交叉DES加解密的问题
来源:互联网 发布:南京国土局网络问政 编辑:程序博客网 时间:2024/05/14 05:21
何为交叉加解密?
——Java加密、Delphi解密,或 Delphi加密、Java解密。
近日,手头上当前的项目进展到优化、完善阶段,其中一点是需要增强服务端与客户端通信的安全性,考虑采用对报文进行DES加密的方法来实现。
服务端是Java编写的,客户端是Delphi编写的,原以为两端各自coding完进行个联调就OK了,结果发现同样的明文、密钥通过Delphi、Java所产生的密文是不同的。
在网上搜索相关资源,得出结论:
原来这是个普遍存在的问题,主要原因是不同的语言在明文的长度不够8byte倍数时,补充的字节各不相同所致。
Java和C之间已经有解决方案(http://shirlly.iteye.com/blog/310759),而Java和Delphi的已由公司牛人于2009-12-10解决,代码如下:
- import java.security.SecureRandom;
- import javax.crypto.Cipher;
- import javax.crypto.SecretKey;
- import javax.crypto.SecretKeyFactory;
- import javax.crypto.spec.DESKeySpec;
- /**
- * DES加解密,支持与delphi交互(字符串编码需统一为UTF-8)
- *
- * @author wym
- */
- public class DESCipherCrossoverDelphi {
- /**
- * 密钥
- */
- public static final String KEY = "12345678";
- private final static String DES = "DES";
- /**
- * 加密
- *
- * @param src
- * 明文(字节)
- * @param key
- * 密钥,长度必须是8的倍数
- * @return 密文(字节)
- * @throws Exception
- */
- public static byte[] encrypt(byte[] src, byte[] key) throws Exception {
- // DES算法要求有一个可信任的随机数源
- SecureRandom sr = new SecureRandom();
- // 从原始密匙数据创建DESKeySpec对象
- DESKeySpec dks = new DESKeySpec(key);
- // 创建一个密匙工厂,然后用它把DESKeySpec转换成
- // 一个SecretKey对象
- SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
- SecretKey securekey = keyFactory.generateSecret(dks);
- // Cipher对象实际完成加密操作
- Cipher cipher = Cipher.getInstance(DES);
- // 用密匙初始化Cipher对象
- cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
- // 现在,获取数据并加密
- // 正式执行加密操作
- return cipher.doFinal(src);
- }
- /**
- * 解密
- *
- * @param src
- * 密文(字节)
- * @param key
- * 密钥,长度必须是8的倍数
- * @return 明文(字节)
- * @throws Exception
- */
- public static byte[] decrypt(byte[] src, byte[] key) throws Exception {
- // DES算法要求有一个可信任的随机数源
- SecureRandom sr = new SecureRandom();
- // 从原始密匙数据创建一个DESKeySpec对象
- DESKeySpec dks = new DESKeySpec(key);
- // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成
- // 一个SecretKey对象
- SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
- SecretKey securekey = keyFactory.generateSecret(dks);
- // Cipher对象实际完成解密操作
- Cipher cipher = Cipher.getInstance(DES);
- // 用密匙初始化Cipher对象
- cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
- // 现在,获取数据并解密
- // 正式执行解密操作
- return cipher.doFinal(src);
- }
- /**
- * 加密
- *
- * @param src
- * 明文(字节)
- * @return 密文(字节)
- * @throws Exception
- */
- public static byte[] encrypt(byte[] src) throws Exception {
- return encrypt(src, KEY.getBytes());
- }
- /**
- * 解密
- *
- * @param src
- * 密文(字节)
- * @return 明文(字节)
- * @throws Exception
- */
- public static byte[] decrypt(byte[] src) throws Exception {
- return decrypt(src, KEY.getBytes());
- }
- /**
- * 加密
- *
- * @param src
- * 明文(字符串)
- * @return 密文(16进制字符串)
- * @throws Exception
- */
- public final static String encrypt(String src) {
- try {
- return byte2hex(encrypt(src.getBytes(), KEY.getBytes()));
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- /**
- * 解密
- *
- * @param src
- * 密文(字符串)
- * @return 明文(字符串)
- * @throws Exception
- */
- public final static String decrypt(String src) {
- try {
- return new String(decrypt(hex2byte(src.getBytes()), KEY.getBytes()));
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- /**
- * 加密
- *
- * @param src
- * 明文(字节)
- * @return 密文(16进制字符串)
- * @throws Exception
- */
- public static String encryptToString(byte[] src) throws Exception {
- return encrypt(new String(src));
- }
- /**
- * 解密
- *
- * @param src
- * 密文(字节)
- * @return 明文(字符串)
- * @throws Exception
- */
- public static String decryptToString(byte[] src) throws Exception {
- return decrypt(new String(src));
- }
- public static String byte2hex(byte[] b) {
- String hs = "";
- String stmp = "";
- for (int n = 0; n < b.length; n++) {
- stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
- if (stmp.length() == 1)
- hs = hs + "0" + stmp;
- else
- hs = hs + stmp;
- }
- return hs.toUpperCase();
- }
- public static byte[] hex2byte(byte[] b) {
- if ((b.length % 2) != 0)
- throw new IllegalArgumentException("长度不是偶数");
- byte[] b2 = new byte[b.length / 2];
- for (int n = 0; n < b.length; n += 2) {
- String item = new String(b, n, 2);
- b2[n / 2] = (byte) Integer.parseInt(item, 16);
- }
- return b2;
- }
- public static void main(String[] args) {
- try {
- String src = "测试";
- String crypto = DESCipherCrossoverDelphi.encrypt(src);
- System.out.println("密文[" + src + "]:" + crypto);
- System.out.println("解密后:"
- + DESCipherCrossoverDelphi.decrypt(crypto));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
main函数运行结果如下:
- 密文[测试]:F25C2FB5F47CCE5F
- 解密后:测试
- Java与Delphi交叉DES加解密的问题
- DES 算法的 C++ 与 JAVA 互相加解密
- DES 算法的 C++ 与 JAVA 互相加解密
- Objective C与Java之间的DES加解密实现
- DES 算法的 C++ 与 JAVA 互相加解密
- GO与Java的DES ECB加解密算法互换
- PHP的DES加解密函数 与JAVA兼容
- java与js端的des加解密
- java 与 c# 3des 加解密
- Android(java)与C#,DES加解密
- java 与 c# 3des 加解密
- DES加解密(Java)
- Java Des加解密
- java des加解密
- java des 加解密
- java DES加解密
- DES加解密(Java)
- ios des加密与解密(对应JAVA加解密)
- 将字符串转为数字
- SQL行列转换-合并列值(示例)
- expect的基本用法
- SQL 中字符串连接
- 用二级指针删除单链表的一个节点
- Java与Delphi交叉DES加解密的问题
- 在 Ubuntu 12.04 Server 中修改用户名和主机名
- 读取中英文混搭的文件
- Windows界面编程第六篇 动画启动效果(动画效果显示及隐藏窗口)
- jQuery窗口、文档各种高度的理解
- PCI配置空间的访问方式
- Android 4.0.x 浏览器不触发 ontouchend 事件的解决
- sql知识
- Centos6.4-32(VM8.x)