对称加密算法
定义:在对称加密算法中,数据发信方将明文(原始数据)和加密密钥(mi yue)一起经过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则需要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥。
优点:算法公开、计算量小、加密速度快、加密效率高。
缺点:
(1)交易双方都使用同样钥匙,安全性得不到保证。
(2)每对用户每次使用对称加密算法时,都需要使用其他人不知道的惟一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增长,密钥管理成为用户的负担。对称加密算法在分布式网络系统上使用较为困难,主要是因为密钥管理困难,使用成本较高。
AES五种加密模式
电码本模式(ECB)
将整个明文分成若干段相同的小段,然后对每一小段进行加密。
优:操作简单,易于实现;分组独立,易于并行;误差不会被传送。——简单,可并行,不传送误差。
缺:掩盖不了明文结构信息,难以抵抗统计分析攻击。——可对明文进行主动攻击。
密码分组链模式(CBC)
先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。
优点:能掩盖明文结构信息,保证相同密文可得不同明文,所以不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL和IPSec的标准。
缺点:(1)不利于并行计算;(2)传递误差——前一个出错则后续全错;(3)第一个明文块需要与一个初始化向量IV进行异或,初始化向量IV的选取比较复杂。
输出反馈模式(OFB)
密码算法的输出(指密码key而不是密文)会反馈到密码算法的输入中,OFB模式并不是通过密码算法对明文直接加密,而是通过将明文分组和密码算法的输出进行XOR来产生密文分组。
优点:隐藏了明文模式;结合了分组加密和流密码(分组密码转化为流模式);可以及时加密传送小于分组的数据。
缺点:不利于并行计算;需要生成秘钥流;对明文的主动攻击是可能的。
计数器模式(CTR)
完全的流模式。将瞬时值与计数器连接起来,然后对此进行加密产生密钥流的一个密钥块,再进行XOR操作 。
优点:不泄露明文;仅需实现加密函数;无需填充;可并行计算。
缺点:需要瞬时值IV,难以保证IV的唯一性。
密码反馈模式(Cipher FeedBack (CFB))
与ECB和CBC模式只能够加密块数据不同,CFB能够将块密文(Block Cipher)转换为流密文(Stream Cipher)。
AES的填充模式
Java中AES的实现
1 /** 2 3 * AES加密字符串 4 5 * 6 7 * @param content 8 9 * 需要被加密的字符串 10 11 * @param password 12 13 * 加密需要的密码 14 15 * @return 密文 16 17 */ 18 19 public static byte[] encrypt(String content, String password) { 20 21 try { 22 23 // KeyGenerator类是java提供的密钥生成器 24 25 KeyGenerator kgen = KeyGenerator.getInstance("AES"); 26 // 根据用户密码,生成一个密钥 27 // 利用用户密码作为随机数初始化出 28 //加密没关系,SecureRandom是生成安全随机数序列,password.getBytes()是种子,只要种子相同,序列就一样,所以解密只要有password就行 //SecureRandom类是java中提供强加密随机数生成器 (RNG)。 29 kgen.init(128, new SecureRandom(password.getBytes()));// 128位的key生产者 30 //生成一个密钥 35 SecretKey secretKey = kgen.generateKey(); 36 37 // 返回基本编码格式的密钥,如果此密钥不支持编码,则返回null 38 39 byte[] enCodeFormat = secretKey.getEncoded(); 40 41 // 转换为AES专用密钥 42 43 SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES"); 44 45 // 创建密码器。Cipher类为加密和解密提供密码功能 46 47 Cipher cipher = Cipher.getInstance("AES"); 48 49 byte[] byteContent = content.getBytes("utf-8"); 50 51 // 初始化为加密模式的密码器。DECRYPT_MODE用于将 Cipher 初始化为解密模式的常量。用密钥初始化此 Cipher。 52 53 cipher.init(Cipher.ENCRYPT_MODE, key); 54 //按单部分操作加密或解密数据,或者结束一个多部分操作。数据将被加密或解密 55 byte[] result = cipher.doFinal(byteContent);// 加密 56 57 return result; 58 59 60 61 } catch (Exception e) { 62 63 e.printStackTrace(); 64 65 } 87 return null; 88 89 }
解密
1 KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者 2 kgen.init(128, new SecureRandom(password.getBytes())); 3 SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个密钥 4 byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥 5 SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥 6 Cipher cipher = Cipher.getInstance("AES");// 创建密码器 7 cipher.init(Cipher.DECRYPT_MODE, key);// 初始化为解密模式的密码器 8 byte[] result = cipher.doFinal(content); 9 return result; // 明文