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解决,代码如下:

 

 

Java代码  
  1. import java.security.SecureRandom;  
  2.   
  3. import javax.crypto.Cipher;  
  4. import javax.crypto.SecretKey;  
  5. import javax.crypto.SecretKeyFactory;  
  6. import javax.crypto.spec.DESKeySpec;  
  7.   
  8. /** 
  9.  * DES加解密,支持与delphi交互(字符串编码需统一为UTF-8) 
  10.  *  
  11.  * @author wym 
  12.  */  
  13.   
  14. public class DESCipherCrossoverDelphi {  
  15.   
  16.     /** 
  17.      * 密钥 
  18.      */  
  19.     public static final String KEY = "12345678";  
  20.   
  21.     private final static String DES = "DES";  
  22.   
  23.     /** 
  24.      * 加密 
  25.      *  
  26.      * @param src 
  27.      *            明文(字节) 
  28.      * @param key 
  29.      *            密钥,长度必须是8的倍数 
  30.      * @return 密文(字节) 
  31.      * @throws Exception 
  32.      */  
  33.     public static byte[] encrypt(byte[] src, byte[] key) throws Exception {  
  34.         // DES算法要求有一个可信任的随机数源  
  35.         SecureRandom sr = new SecureRandom();  
  36.         // 从原始密匙数据创建DESKeySpec对象  
  37.         DESKeySpec dks = new DESKeySpec(key);  
  38.         // 创建一个密匙工厂,然后用它把DESKeySpec转换成  
  39.         // 一个SecretKey对象  
  40.         SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);  
  41.         SecretKey securekey = keyFactory.generateSecret(dks);  
  42.         // Cipher对象实际完成加密操作  
  43.         Cipher cipher = Cipher.getInstance(DES);  
  44.         // 用密匙初始化Cipher对象  
  45.         cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);  
  46.         // 现在,获取数据并加密  
  47.         // 正式执行加密操作  
  48.         return cipher.doFinal(src);  
  49.     }  
  50.   
  51.     /** 
  52.      * 解密 
  53.      *  
  54.      * @param src 
  55.      *            密文(字节) 
  56.      * @param key 
  57.      *            密钥,长度必须是8的倍数 
  58.      * @return 明文(字节) 
  59.      * @throws Exception 
  60.      */  
  61.     public static byte[] decrypt(byte[] src, byte[] key) throws Exception {  
  62.         // DES算法要求有一个可信任的随机数源  
  63.         SecureRandom sr = new SecureRandom();  
  64.         // 从原始密匙数据创建一个DESKeySpec对象  
  65.         DESKeySpec dks = new DESKeySpec(key);  
  66.         // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成  
  67.         // 一个SecretKey对象  
  68.         SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);  
  69.         SecretKey securekey = keyFactory.generateSecret(dks);  
  70.         // Cipher对象实际完成解密操作  
  71.         Cipher cipher = Cipher.getInstance(DES);  
  72.         // 用密匙初始化Cipher对象  
  73.         cipher.init(Cipher.DECRYPT_MODE, securekey, sr);  
  74.         // 现在,获取数据并解密  
  75.         // 正式执行解密操作  
  76.         return cipher.doFinal(src);  
  77.     }  
  78.   
  79.     /** 
  80.      * 加密 
  81.      *  
  82.      * @param src 
  83.      *            明文(字节) 
  84.      * @return 密文(字节) 
  85.      * @throws Exception 
  86.      */  
  87.     public static byte[] encrypt(byte[] src) throws Exception {  
  88.         return encrypt(src, KEY.getBytes());  
  89.     }  
  90.   
  91.     /** 
  92.      * 解密 
  93.      *  
  94.      * @param src 
  95.      *            密文(字节) 
  96.      * @return 明文(字节) 
  97.      * @throws Exception 
  98.      */  
  99.     public static byte[] decrypt(byte[] src) throws Exception {  
  100.         return decrypt(src, KEY.getBytes());  
  101.     }  
  102.   
  103.     /** 
  104.      * 加密 
  105.      *  
  106.      * @param src 
  107.      *            明文(字符串) 
  108.      * @return 密文(16进制字符串) 
  109.      * @throws Exception 
  110.      */  
  111.     public final static String encrypt(String src) {  
  112.         try {  
  113.             return byte2hex(encrypt(src.getBytes(), KEY.getBytes()));  
  114.         } catch (Exception e) {  
  115.             e.printStackTrace();  
  116.         }  
  117.         return null;  
  118.     }  
  119.   
  120.     /** 
  121.      * 解密 
  122.      *  
  123.      * @param src 
  124.      *            密文(字符串) 
  125.      * @return 明文(字符串) 
  126.      * @throws Exception 
  127.      */  
  128.     public final static String decrypt(String src) {  
  129.         try {  
  130.             return new String(decrypt(hex2byte(src.getBytes()), KEY.getBytes()));  
  131.         } catch (Exception e) {  
  132.             e.printStackTrace();  
  133.         }  
  134.         return null;  
  135.     }  
  136.   
  137.     /** 
  138.      * 加密 
  139.      *  
  140.      * @param src 
  141.      *            明文(字节) 
  142.      * @return 密文(16进制字符串) 
  143.      * @throws Exception 
  144.      */  
  145.     public static String encryptToString(byte[] src) throws Exception {  
  146.         return encrypt(new String(src));  
  147.     }  
  148.   
  149.     /** 
  150.      * 解密 
  151.      *  
  152.      * @param src 
  153.      *            密文(字节) 
  154.      * @return 明文(字符串) 
  155.      * @throws Exception 
  156.      */  
  157.     public static String decryptToString(byte[] src) throws Exception {  
  158.         return decrypt(new String(src));  
  159.     }  
  160.   
  161.     public static String byte2hex(byte[] b) {  
  162.         String hs = "";  
  163.         String stmp = "";  
  164.         for (int n = 0; n < b.length; n++) {  
  165.             stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));  
  166.             if (stmp.length() == 1)  
  167.                 hs = hs + "0" + stmp;  
  168.             else  
  169.                 hs = hs + stmp;  
  170.         }  
  171.         return hs.toUpperCase();  
  172.     }  
  173.   
  174.     public static byte[] hex2byte(byte[] b) {  
  175.         if ((b.length % 2) != 0)  
  176.             throw new IllegalArgumentException("长度不是偶数");  
  177.         byte[] b2 = new byte[b.length / 2];  
  178.         for (int n = 0; n < b.length; n += 2) {  
  179.             String item = new String(b, n, 2);  
  180.             b2[n / 2] = (byte) Integer.parseInt(item, 16);  
  181.         }  
  182.         return b2;  
  183.     }  
  184.   
  185.     public static void main(String[] args) {  
  186.         try {  
  187.             String src = "测试";  
  188.             String crypto = DESCipherCrossoverDelphi.encrypt(src);  
  189.             System.out.println("密文[" + src + "]:" + crypto);  
  190.             System.out.println("解密后:"  
  191.                     + DESCipherCrossoverDelphi.decrypt(crypto));  
  192.         } catch (Exception e) {  
  193.             e.printStackTrace();  
  194.         }  
  195.     }  
  196.   
  197. }  

 

 

    main函数运行结果如下:

Java代码  
  1. 密文[测试]:F25C2FB5F47CCE5F  
  2. 解密后:测试 
原创粉丝点击