有两句话是这么说的:
1)算法和数据结构就是编程的一个重要部分,你若失掉了算法和数据结构,你就把一切都失掉了。
2)编程就是算法和数据结构,算法和数据结构是编程的灵魂。
注意,这可不是我说的,是无数程序员总结的,话说的很实在也很精辟,若想长久可持续发展,多研究算法还是很有必要的,今天我给大家说说加密算法中的对称加密算法,并且这里将教会大家对称加密算法的编程使用。包含DES、3DES和AES三种对称加密算法的编程使用,干货满满。
1.对称密码算法
对称密码算法是当今应用范围最广,使用频率最高的加密算法。它不仅应用于软件行业,在硬件行业同样流行。各种基础设施凡是涉及到安全需求,都会优先考虑对称加密算法。
对称密码算法的加密密钥和解密密钥相同,对于大多数对称密码算法,加解密过程互逆。
(1)加解密通信模型
(2)特点:算法公开、计算量小、加密速度快、加密效率高
(3)弱点:双方都使用同样密钥,安全性得不到保证
对称密码有流密码和分组密码两种,但是现在普遍使用的是分组密码:
(4)分组密码工作模式
1)ECB:电子密码本(最常用的,每次加密均产生独立的密文分组,并且对其他的密文分组不会产生影响,也就是相同的明文加密后产生相同的密文)
2)CBC:密文链接(常用的,明文加密前需要先和前面的密文进行异或运算,也就是相同的明文加密后产生不同的密文)
3)CFB:密文反馈
4)OFB:输出反馈
5)CTR:计数器
这五种工作模式主要是密码学中算法在进行推导演算的时候所应用到的。
6.分组密码填充方式
1)NoPadding:无填充
2)PKCS5Padding:
3)ISO10126Padding:
7.常用对称密码:
1)DES(Data Encryption Standard,数据加密标准)
2)3DES(Triple DES、DESede,进行了三重DES加密的算法)
3)AES(Advanced Encryption Standard,高级数据加密标准,AES算法可以有效抵制针对DES的攻击算法)
先来看一下这三种算法的简单对比:
下面我们看如何使用 DES / 3DES / AES 三种算法实现 对称加密:
2.DES算法
DES:数据加密标准,是对称加密算法领域中的典型算法
特点:密钥偏短(56位)、生命周期短(避免被破解)
Java实现
1)生成密钥
KeyGenerator keyGen = KeyGenerator.getInstance("DES");//密钥生成器 keyGen.init(56);//初始化密钥生成器 SecretKey secretKey = keyGen.generateKey();//生成密钥 byte[] key = secretKey.getEncoded();//密钥字节数组
2)加密
SecretKey secretKey = new SecretKeySpec(key, "DES");//恢复密钥 Cipher cipher = Cipher.getInstance("DES");//Cipher完成加密或解密工作类 cipher.init(Cipher.ENCRYPT_MODE, secretKey);//对Cipher初始化,加密模式 byte[] cipherByte = cipher.doFinal(data);//加密data
3)解密
SecretKey secretKey = new SecretKeySpec(key, "DES");//恢复密钥 Cipher cipher = Cipher.getInstance("DES");//Cipher完成加密或解密工作类 cipher.init(Cipher.DECRYPT_MODE, secretKey);//对Cipher初始化,解密模式 byte[] cipherByte = cipher.doFinal(data);//解密data
我们可以发现,加密解密我们只是设置了不同的模式而已。
若要指定加密解密的工作模式和填充方式,只需要在加密解密方法中,指定即可,测试例子如下
加密/解密方法的这一句 Cipher cipher = Cipher.getInstance("DES"); 修改为 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); 若要指定CBC工作模式,需要将加密/解密方法中 Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); 修改为 Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); IvParameterSpec iv = new IvParameterSpec(key); cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); // ECB方式不能使用IvParameterSpec
DES加密/解密 测试代码
首先定义一个字节数组转化工具
/** * 字节数组转化工具 */ public class BytesToHex { /** * 字节数组转化为十六进制BytesToHex * * @param resultBytes * @return */ public static String fromBytesToHex(byte[] resultBytes) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < resultBytes.length; i++) { String hv = Integer.toHexString(0xFF & resultBytes[i]); if (hv.length() == 1) { builder.append("0").append(hv); } else { builder.append(hv); } } return builder.toString(); } }
DES 测试代码
import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; /** * DES,3DES,AES对称加密解密工具类 */ public class DESUtil { /** * 初始化DES密钥 * * @return * @throws Exception */ public static byte[] DES_init() throws Exception { KeyGenerator keyGen = KeyGenerator.getInstance("DES");// 密钥生成器 keyGen.init(56);// 初始化长度,默认56 SecretKey secretKey = keyGen.generateKey();// 生成密钥 byte[] key = secretKey.getEncoded();// 密钥字节数组 return key; } /** * DES 加密 * * @param data 加密数据 * @param key 密钥 * @return * @throws Exception */ public static byte[] DES_encrypt(byte[] data, byte[] key) throws Exception { SecretKey secretKey = new SecretKeySpec(key, "DES"); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] cipherBytes = cipher.doFinal(data); return cipherBytes; } /** * DES 解密 * * @param data 加密密文 * @param key 密钥 * @return * @throws Exception */ public static byte[] DES_decrypt(byte[] data, byte[] key) throws Exception { SecretKey secretKey = new SecretKeySpec(key, "DES"); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] decrypt = cipher.doFinal(data); return decrypt; } public static void main(String[] args) { try { // 初始化 DES 密钥 String data = "嫚儿 我爱你"; byte[] desKey = DES_init(); System.out.println("DES Key:" + BytesToHex.fromBytesToHex(desKey)); // DES 加密 byte[] desResult = DES_encrypt(data.getBytes(), desKey); System.out.println(data + " >>> DES 加密 >>> " + BytesToHex.fromBytesToHex(desResult)); // DES 解密 byte[] desPlain = DES_decrypt(desResult, desKey); System.out.println(data + " >>> DES 解密 >>> " + new String(desPlain)); } catch (Exception e) { e.printStackTrace(); } } } 输出 DES Key:0eb592bc757c67fb 嫚儿 我爱你 >>> DES 加密 >>> 30af9d9b463ed4a8ad0264f0e03f94f92658b4ca13b4ab6c 嫚儿 我爱你 >>> DES 解密 >>> 嫚儿 我爱你
3.3DES算法
3DES:将密钥长度增至112位或168位,通过增加迭代次数提高安全性
缺点:处理速度较慢、密钥计算时间较长、加密效率不高
Java实现
1)生成密钥
KeyGenerator keyGen = KeyGenerator.getInstance("DESede");//密钥生成器 keyGen.init(168); //可指定密钥长度为112或168,默认为168 SecretKey secretKey = keyGen.generateKey();//生成密钥 byte[] key = secretKey.getEncoded();//密钥字节数组
2)3DES加密
SecretKey secretKey = new SecretKeySpec(key, "DESede");//恢复密钥 Cipher cipher = Cipher.getInstance("DESede");//Cipher完成加密或解密工作类 cipher.init(Cipher.ENCRYPT_MODE, secretKey);//对Cipher初始化,解密模式 byte[] cipherByte = cipher.doFinal(data);//加密data
3)3DES解密
SecretKey secretKey = new SecretKeySpec(key, "DESede");//恢复密钥 Cipher cipher = Cipher.getInstance("DESede");//Cipher完成加密或解密工作类 cipher.init(Cipher.DECRYPT_MODE, secretKey);//对Cipher初始化,解密模式 byte[] cipherByte = cipher.doFinal(data);//解密data
4.AES算法(推荐使用)
AES:高级数据加密标准,能够有效抵御已知的针对DES算法的所有攻击
特点:密钥建立时间短、灵敏性好、内存需求低、安全性高
Java实现
1)生成密钥
KeyGenerator keyGen = KeyGenerator.getInstance("AES");//密钥生成器 keygen.init(128); //默认128,获得无政策权限后可为192或256 SecretKey secretKey = keyGen.generateKey();//生成密钥 byte[] key = secretKey.getEncoded();//密钥字节数组
2)AES加密
SecretKey secretKey = new SecretKeySpec(key, "AES");//恢复密钥 Cipher cipher = Cipher.getInstance("AES");//Cipher完成加密或解密工作类 cipher.init(Cipher.ENCRYPT_MODE, secretKey);//对Cipher初始化,解密模式 byte[] cipherByte = cipher.doFinal(data);//加密data
3)AES解密
SecretKey secretKey = new SecretKeySpec(key, "AES");//恢复密钥 Cipher cipher = Cipher.getInstance("AES");//Cipher完成加密或解密工作类 cipher.init(Cipher.DECRYPT_MODE, secretKey);//对Cipher初始化,解密模式 byte[] cipherByte = cipher.doFinal(data);//解密data
为了方便使用,我对DES / 3DES / AES 三种算法进行了工具类编写
地址:https://github.com/smartbetter/Android-UtilsLibrary (新增DES/3DES/AES工具类)。
via:http://blog.csdn.net/smartbetter/article/details/54017759