3DES加密算法
在日常设计及开发中,为确保数据传输和数据存储的安全,可通过特定的算法,将数据明文加密成复杂的密文。目前主流加密手段大致可分为单向加密和双向加密。
单向加密:通过对数据进行摘要计算生成密文,密文不可逆推还原。算法代表:Base64,MD5,SHA;
双向加密:与单向加密相反,可以把密文逆推还原成明文,双向加密又分为对称加密和非对称加密。
对称加密:指数据使用者必须拥有相同的密钥才可以进行加密解密,就像彼此约定的一串暗号。算法代表:DES,3DES,AES,IDEA,RC4,RC5;
非对称加密:相对对称加密而言,无需拥有同一组密钥,非对称加密是一种“信息公开的密钥交换协议”。非对称加密需要公开密钥和私有密钥两组密钥,公开密钥和私有密钥是配对起来的,也就是说使用公开密钥进行数据加密,只有对应的私有密钥才能解密。这两个密钥是数学相关,用某用户密钥加密后的密文,只能使用该用户的加密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个密钥性质。这里把公开的密钥为公钥,不公开的密钥为私钥。算法代表:RSA,DSA。
======================================================
3DES算法
3DES是三重数据加密,且可以逆推的一种算法方案。但由于3DES的算法是公开的,所以算法本身没有密钥可言,主要依靠唯一密钥来确保数据加解密的安全。到目前为止,仍没有人能破解3DES。
【3DES加密类】
package com.mes.util; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.IvParameterSpec; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; @SuppressWarnings({ "restriction" }) public class ThreeDES { private static final String IV = "1234567-"; public static final String KEY = "uatspdbcccgame2014061800"; /** * DESCBC加密 * * @param src * 数据源 * @param key * 密钥,长度必须是8的倍数 * @return 返回加密后的数据 * @throws Exception */ public String encryptDESCBC(final String src, final String key) throws Exception { // --生成key,同时制定是des还是DESede,两者的key长度要求不同 final DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8")); final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); final SecretKey secretKey = keyFactory.generateSecret(desKeySpec); // --加密向量 final IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8")); // --通过Chipher执行加密得到的是一个byte的数组,Cipher.getInstance("DES")就是采用ECB模式,cipher.init(Cipher.ENCRYPT_MODE, // secretKey)就可以了. final Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); final byte[] b = cipher.doFinal(src.getBytes("UTF-8")); // --通过base64,将加密数组转换成字符串 final BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(b); } /** * DESCBC解密 * * @param src * 数据源 * @param key * 密钥,长度必须是8的倍数 * @return 返回解密后的原始数据 * @throws Exception */ public String decryptDESCBC(final String src, final String key) throws Exception { // --通过base64,将字符串转成byte数组 final BASE64Decoder decoder = new BASE64Decoder(); final byte[] bytesrc = decoder.decodeBuffer(src); // --解密的key final DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8")); final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); final SecretKey secretKey = keyFactory.generateSecret(desKeySpec); // --向量 final IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8")); // --Chipher对象解密Cipher.getInstance("DES")就是采用ECB模式,cipher.init(Cipher.DECRYPT_MODE, // secretKey)就可以了. final Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secretKey, iv); final byte[] retByte = cipher.doFinal(bytesrc); return new String(retByte); } // 3DESECB加密,key必须是长度大于等于 3*8 = 24 位哈 public String encryptThreeDESECB(final String src, final String key) throws Exception { final DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8")); final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); final SecretKey securekey = keyFactory.generateSecret(dks); final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, securekey); final byte[] b = cipher.doFinal(src.getBytes()); final BASE64Encoder encoder = new BASE64Encoder(); return encoder.encode(b).replaceAll("\r", "").replaceAll("\n", ""); } // 3DESECB解密,key必须是长度大于等于 3*8 = 24 位哈 public String decryptThreeDESECB(final String src, final String key) throws Exception { // --通过base64,将字符串转成byte数组 final BASE64Decoder decoder = new BASE64Decoder(); final byte[] bytesrc = decoder.decodeBuffer(src); // --解密的key final DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8")); final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede"); final SecretKey securekey = keyFactory.generateSecret(dks); // --Chipher对象解密 final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, securekey); final byte[] retByte = cipher.doFinal(bytesrc); return new String(retByte); } }
【测试类】
package test; import java.net.URLEncoder; import com.mes.util.ThreeDES; public class ThreeDES_TEST { public static void main(String[] args) throws Exception { final String key = "cf410f84904a44cc8a7f48fc4134e8f9"; // 加密流程 String telePhone = "15629551180"; ThreeDES threeDES = new ThreeDES(); String telePhone_encrypt = ""; telePhone_encrypt = threeDES.encryptThreeDESECB(URLEncoder.encode(telePhone, "UTF-8"), key); System.out.println(telePhone_encrypt);// nWRVeJuoCrs8a+Ajn/3S8g== // 解密流程 String tele_decrypt = threeDES.decryptThreeDESECB(telePhone_encrypt, key); System.out.println("模拟代码解密:" + tele_decrypt); } }
【测试结果】
Bu7KzIWrplmh4nVj0d2Htg==
模拟代码解密:15629551180
附件:生产3des密钥的方法请参考:http://www.cnblogs.com/shindo/p/5995849.html
注意:
3DES密钥的长度必须是8的倍数,可取24位或32位;
加密结果的byte数组转换为字符串,一般采用两种方式:Base64处理或十六进制处理。