1、Java 加密解密之对称加密算法 AES本文转自网络密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael 加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的 DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院 (NIST )于 2001 年 11 月 26 日发布于 FIPS PUB 197,并在 2002 年 5 月 26 日成为有效的标准。2006 年,高级加密标准已然成为对称密钥加密中最流行的算法之一。该算法为比利时密码学家 Joan Daemen 和 Vinc
2、ent Rijmen 所设计,结合两位作者的名字,以Rijndael 之命名之,投稿高级加密标准的甄选流程。(Rijdael 的发音近于 “Rhinedoll“。)AES 是美国国家标准技术研究所 NIST 旨在取代 DES 的 21 世纪的加密标准。AES 的基本要求是,采用对称分组密码体制,密钥长度的最少支持为128、192、256,分组长度 128 位,算法应易于各种硬件和软件实现。 1998年 NIST 开始 AES 第一轮分析、测试和征集,共产生了 15 个候选算法。1999年 3 月完成了第二轮 AES2 的分析、测试。2000 年 10 月 2 日美国政府正式宣布选中比利时密码学
3、家 Joan Daemen 和 Vincent Rijmen 提出的一种密码算法 RIJNDAEL 作为 AES. 在应用方面,尽管 DES 在安全上是脆弱的,但由于快速 DES 芯片的大量生产,使得 DES 仍能暂时继续使用,为提高安全强度,通常使用独立密钥的三级 DES。但是 DES 迟早要被 AES 代替。流密码体制较之分组密码在理论上成熟且安全,但未被列入下一代加密标准。 AES 加密数据块和密钥长度可以是 128 比特、192 比特、256 比特中的任意一个。AES 加密有很多轮的重复和变换。大致步骤如下:1、密钥扩展( KeyExpansion),2、初始轮( Initial Ro
4、und),3、重复轮( Rounds),每一轮又包括:SubBytes、ShiftRows、MixColumns、AddRoundKey,4、最终轮( Final Round),最终轮没有 MixColumns。JDK 对 DESede 算法的支持密钥长度:128 位工作模式:ECB/CBC/PCBC/CTR/CTS/CFB/CFB8 to CFB128/OFB/OBF8 to OFB128填充方式:Nopadding/PKCS5Padding/ISO10126Padding/工作模式和填充方式请参考: JAVA 加密解密基础十六进制工具类 Hex.java,见: java byte 数组与十
5、六进制字符串互转 AES 加密解密的 java 实现:AESCoder.javaJava 代码 1. import java.security.Key; 2. import java.security.NoSuchAlgorithmException; 3. 4. import javax.crypto.Cipher; 5. import javax.crypto.KeyGenerator; 6. import javax.crypto.SecretKey; 7. import javax.crypto.spec.SecretKeySpec; 8. 9. /* 10. * AES Coder
6、11. * secret key length: 128bit, default: 128 bit 12. * mode: ECB/CBC/PCBC/CTR/CTS/CFB/CFB8 to CFB128/OFB/OBF8 to OFB128 13. * padding: Nopadding/PKCS5Padding/ISO10126Padding/ 14. * author Aub 15. * 16. */ 17. public class AESCoder 18. 19. /* 20. * 密钥算法 21. */ 22. private static final String KEY_ALG
7、ORITHM = “AES“; 23. 24. private static final String DEFAULT_CIPHER_ALGORITHM = “AES/ECB/PKCS5Padding“; 25. 26. /* 27. * 初始化密钥 28. * 29. * return byte 密钥 30. * throws Exception 31. */ 32. public static byte initSecretKey() 33. /返回生成指定算法的秘密密钥的 KeyGenerator 对象 34. KeyGenerator kg = null; 35. try 36. kg
8、 = KeyGenerator.getInstance(KEY_ALGORITHM); 37. catch (NoSuchAlgorithmException e) 38. e.printStackTrace(); 39. return new byte0; 40. 41. /初始化此密钥生成器,使其具有确定的密钥大小 42. /AES 要求密钥长度为 128 43. kg.init(128); 44. /生成一个密钥 45. SecretKey secretKey = kg.generateKey(); 46. return secretKey.getEncoded(); 47. 48. 4
9、9. /* 50. * 转换密钥 51. * 52. * param key 二进制密钥 53. * return 密钥 54. */ 55. private static Key toKey(byte key) 56. /生成密钥 57. return new SecretKeySpec(key, KEY_ALGORITHM); 58. 59. 60. /* 61. * 加密 62. * 63. * param data 待加密数据 64. * param key 密钥 65. * return byte 加密数据 66. * throws Exception 67. */ 68. publ
10、ic static byte encrypt(byte data,Key key) throws Exception 69. return encrypt(data, key,DEFAULT_CIPHER_ALGORITHM); 70. 71. 72. /* 73. * 加密 74. * 75. * param data 待加密数据 76. * param key 二进制密钥 77. * return byte 加密数据 78. * throws Exception 79. */ 80. public static byte encrypt(byte data,byte key) throws
11、 Exception 81. return encrypt(data, key,DEFAULT_CIPHER_ALGORITHM); 82. 83. 84. 85. /* 86. * 加密 87. * 88. * param data 待加密数据 89. * param key 二进制密钥 90. * param cipherAlgorithm 加密算法/工作模式/填充方式 91. * return byte 加密数据 92. * throws Exception 93. */ 94. public static byte encrypt(byte data,byte key,String c
12、ipherAlgorithm) throws Exception 95. /还原密钥 96. Key k = toKey(key); 97. return encrypt(data, k, cipherAlgorithm); 98. 99. 100. /* 101. * 加密 102. * 103. * param data 待加密数据 104. * param key 密钥 105. * param cipherAlgorithm 加密算法/工作模式/填充方式 106. * return byte 加密数据 107. * throws Exception 108. */ 109. publi
13、c static byte encrypt(byte data,Key key,String cipherAlgorithm) throws Exception 110. /实例化 111. Cipher cipher = Cipher.getInstance(cipherAlgorithm); 112. /使用密钥初始化,设置为加密模式 113. cipher.init(Cipher.ENCRYPT_MODE, key); 114. /执行操作 115. return cipher.doFinal(data); 116. 117. 118. 119. 120. /* 121. * 解密 12
14、2. * 123. * param data 待解密数据 124. * param key 二进制密钥 125. * return byte 解密数据 126. * throws Exception 127. */ 128. public static byte decrypt(byte data,byte key) throws Exception 129. return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM); 130. 131. 132. /* 133. * 解密 134. * 135. * param data 待解密数据 136. *
15、param key 密钥 137. * return byte 解密数据 138. * throws Exception 139. */ 140. public static byte decrypt(byte data,Key key) throws Exception 141. return decrypt(data, key,DEFAULT_CIPHER_ALGORITHM); 142. 143. 144. /* 145. * 解密 146. * 147. * param data 待解密数据 148. * param key 二进制密钥 149. * param cipherAlgor
16、ithm 加密算法/工作模式/填充方式 150. * return byte 解密数据 151. * throws Exception 152. */ 153. public static byte decrypt(byte data,byte key,String cipherAlgorithm) throws Exception 154. /还原密钥 155. Key k = toKey(key); 156. return decrypt(data, k, cipherAlgorithm); 157. 158. 159. /* 160. * 解密 161. * 162. * param d
17、ata 待解密数据 163. * param key 密钥 164. * param cipherAlgorithm 加密算法/工作模式/填充方式 165. * return byte 解密数据 166. * throws Exception 167. */ 168. public static byte decrypt(byte data,Key key,String cipherAlgorithm) throws Exception 169. /实例化 170. Cipher cipher = Cipher.getInstance(cipherAlgorithm); 171. /使用密钥初
18、始化,设置为解密模式 172. cipher.init(Cipher.DECRYPT_MODE, key); 173. /执行操作 174. return cipher.doFinal(data); 175. 176. 177. private static String showByteArray(byte data) 178. if(null = data) 179. return null; 180. 181. StringBuilder sb = new StringBuilder(“); 182. for(byte b:data) 183. sb.append(b).append(“
19、,“); 184. 185. sb.deleteCharAt(sb.length()-1); 186. sb.append(“); 187. return sb.toString(); 188. 189. 190. public static void main(String args) throws Exception 191. byte key = initSecretKey(); 192. System.out.println(“key:“+showByteArray(key); 193. 194. Key k = toKey(key); 195. 196. String data =“
20、AES 数据“; 197. System.out.println(“加密前数据: string:“+data); 198. System.out.println(“加密前数据: byte:“+showByteArray(data.getBytes(); 199. System.out.println(); 200. byte encryptData = encrypt(data.getBytes(), k); 201. System.out.println(“加密后数据: byte:“+showByteArray(encryptData); 202. System.out.println(“加密后数据: hexStr:“+Hex.encodeHexStr(encryptData); 203. System.out.println(); 204. byte decryptData = decrypt(encryptData, k); 205. System.out.println(“解密后数据: byte:“+showByteArray(decryptData); 206. System.out.println(“解密后数据: string:“+new String(decryptData); 207. 208. 209.