Java常用的加密解密类(对称加密类)

Java常用的加密解密类

原文转载至:http://blog.csdn.net/wyc_cs/article/details/8793198

原创 2013年04月12日 14:33:35
  • 1704
最近做一个项目,想到以前所有的项目在用户注册与登录及所有涉及用户自身隐私的信息进行提交到后台时都没有进行加密处理,甚至直接以明文方式在网络上传输,同时直接以明文的方式存到数据库中。所以想到需要先进行加密处理之后再进行网络传输,最后将加密后的数据存到数据库中,这样也可以增强系统的安全性。

对于加密与解密是一个很复杂的学科,如果想了解更深入的加密解密知识可以参考其它资料,本文只讲解一部分加密解密的使用方式。

常用的加密解密可以分为:信息摘要算法:MD5,SHA(也就是单向加密理论上无法解密)、对称加密算法 :DES,3DES,AES、非对称加密算法:RSA,DSA

本文只讲解单向加密和对称加密,关于非对称加密在以后的时间里进行添加。直接上代码,亲测可以运行:

  1. import java.security.MessageDigest;
  2. import java.security.NoSuchAlgorithmException;
  3. import javax.crypto.Cipher;
  4. import javax.crypto.KeyGenerator;
  5. import javax.crypto.SecretKey;
  6. import javax.crypto.spec.SecretKeySpec;
  7. /**
  8. * 加密解密工具类
  9. */
  10. public class EncryptUtils {
  11. /**
  12. * 进行MD5加密
  13. *
  14. * @param info 要加密的信息
  15. * @return String 加密后的字符串
  16. */
  17. public String encryptToMD5(String info) {
  18. byte[] digesta = null;
  19. try {
  20. // 得到一个md5的消息摘要
  21. MessageDigest alga = MessageDigest.getInstance("MD5");
  22. // 添加要进行计算摘要的信息
  23. alga.update(info.getBytes());
  24. // 得到该摘要
  25. digesta = alga.digest();
  26. } catch (NoSuchAlgorithmException e) {
  27. e.printStackTrace();
  28. }
  29. // 将摘要转为字符串
  30. String rs = byte2hex(digesta);
  31. return rs;
  32. }
  33. /**
  34. * 进行SHA加密
  35. *
  36. * @param info 要加密的信息
  37. * @return String 加密后的字符串
  38. */
  39. public String encryptToSHA(String info) {
  40. byte[] digesta = null;
  41. try {
  42. // 得到一个SHA-1的消息摘要
  43. MessageDigest alga = MessageDigest.getInstance("SHA-1");
  44. // 添加要进行计算摘要的信息
  45. alga.update(info.getBytes());
  46. // 得到该摘要
  47. digesta = alga.digest();
  48. } catch (NoSuchAlgorithmException e) {
  49. e.printStackTrace();
  50. }
  51. // 将摘要转为字符串
  52. String rs = byte2hex(digesta);
  53. return rs;
  54. }
  55. /**
  56. * 根据一定的算法得到相应的key
  57. * @param src
  58. * @return
  59. */
  60. public String getKey(String algorithm,String src){
  61. if(algorithm.equals("AES")){
  62. return src.substring(0, 16);
  63. }else if(algorithm.equals("DES")){
  64. return src.substring(0, 8);
  65. }else{
  66. return null;
  67. }
  68. }
  69. /**
  70. * 得到AES加密的key
  71. * @param src
  72. * @return
  73. */
  74. public String getAESKey(String src){
  75. return this.getKey("AES", src);
  76. }
  77. /**
  78. * 得到DES加密的key
  79. * @param src
  80. * @return
  81. */
  82. public String getDESKey(String src){
  83. return this.getKey("DES", src);
  84. }
  85. /**
  86. * 创建密匙
  87. *
  88. * @param algorithm 加密算法,可用 AES,DES,DESede,Blowfish
  89. * @return SecretKey 秘密(对称)密钥
  90. */
  91. public SecretKey createSecretKey(String algorithm) {
  92. // 声明KeyGenerator对象
  93. KeyGenerator keygen;
  94. // 声明 密钥对象
  95. SecretKey deskey = null;
  96. try {
  97. // 返回生成指定算法的秘密密钥的 KeyGenerator 对象
  98. keygen = KeyGenerator.getInstance(algorithm);
  99. // 生成一个密钥
  100. deskey = keygen.generateKey();
  101. } catch (NoSuchAlgorithmException e) {
  102. e.printStackTrace();
  103. }
  104. // 返回密匙
  105. return deskey;
  106. }
  107. /**
  108. * 创建一个AES的密钥
  109. * @return
  110. */
  111. public SecretKey createSecretAESKey() {
  112. return createSecretKey("AES");
  113. }
  114. /**
  115. * 创建一个DES的密钥
  116. * @return
  117. */
  118. public SecretKey createSecretDESKey() {
  119. return createSecretKey("DES");
  120. }
  121. /**
  122. * 根据相应的加密算法、密钥、源文件进行加密,返回加密后的文件
  123. * @param Algorithm 加密算法:DES,AES
  124. * @param key
  125. * @param info
  126. * @return
  127. */
  128. public String encrypt(String Algorithm, SecretKey key, String info) {
  129. // 定义要生成的密文
  130. byte[] cipherByte = null;
  131. try {
  132. // 得到加密/解密器
  133. Cipher c1 = Cipher.getInstance(Algorithm);
  134. // 用指定的密钥和模式初始化Cipher对象
  135. // 参数:(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)
  136. c1.init(Cipher.ENCRYPT_MODE, key);
  137. // 对要加密的内容进行编码处理,
  138. cipherByte = c1.doFinal(info.getBytes());
  139. } catch (Exception e) {
  140. e.printStackTrace();
  141. }
  142. // 返回密文的十六进制形式
  143. return byte2hex(cipherByte);
  144. }
  145. /**
  146. * 根据相应的解密算法、密钥和需要解密的文本进行解密,返回解密后的文本内容
  147. * @param Algorithm
  148. * @param key
  149. * @param sInfo
  150. * @return
  151. */
  152. public String decrypt(String Algorithm, SecretKey key, String sInfo) {
  153. byte[] cipherByte = null;
  154. try {
  155. // 得到加密/解密器
  156. Cipher c1 = Cipher.getInstance(Algorithm);
  157. // 用指定的密钥和模式初始化Cipher对象
  158. c1.init(Cipher.DECRYPT_MODE, key);
  159. // 对要解密的内容进行编码处理
  160. cipherByte = c1.doFinal(hex2byte(sInfo));
  161. } catch (Exception e) {
  162. e.printStackTrace();
  163. }
  164. return new String(cipherByte);
  165. }
  166. /**
  167. * 根据相应的解密算法、指定的密钥和需要解密的文本进行解密,返回解密后的文本内容
  168. * @param Algorithm 加密算法:DES,AES
  169. * @param key 这个key可以由用户自己指定 注意AES的长度为16位,DES的长度为8位
  170. * @param sInfo
  171. * @return
  172. */
  173. public static String decrypt(String Algorithm, String sSrc, String sKey) throws Exception {
  174. try {
  175. // 判断Key是否正确
  176. if (sKey == null) {
  177. throw new Exception("Key为空null");
  178. }
  179. // 判断采用AES加解密方式的Key是否为16位
  180. if (Algorithm.equals("AES") && sKey.length() != 16) {
  181. throw new Exception("Key长度不是16位");
  182. }
  183. // 判断采用DES加解密方式的Key是否为8位
  184. if (Algorithm.equals("DES") && sKey.length() != 8) {
  185. throw new Exception("Key长度不是8位");
  186. }
  187. byte[] raw = sKey.getBytes("ASCII");
  188. SecretKeySpec skeySpec = new SecretKeySpec(raw, Algorithm);
  189. Cipher cipher = Cipher.getInstance(Algorithm);
  190. cipher.init(Cipher.DECRYPT_MODE, skeySpec);
  191. byte[] encrypted1 = hex2byte(sSrc);
  192. try {
  193. byte[] original = cipher.doFinal(encrypted1);
  194. String originalString = new String(original);
  195. return originalString;
  196. } catch (Exception e) {
  197. throw e;
  198. }
  199. } catch (Exception ex) {
  200. throw ex;
  201. }
  202. }
  203. /**
  204. * 根据相应的加密算法、指定的密钥、源文件进行加密,返回加密后的文件
  205. * @param Algorithm 加密算法:DES,AES
  206. * @param key 这个key可以由用户自己指定 注意AES的长度为16位,DES的长度为8位
  207. * @param info
  208. * @return
  209. */
  210. public static String encrypt(String Algorithm, String sSrc, String sKey) throws Exception {
  211. // 判断Key是否正确
  212. if (sKey == null) {
  213. throw new Exception("Key为空null");
  214. }
  215. // 判断采用AES加解密方式的Key是否为16位
  216. if (Algorithm.equals("AES") && sKey.length() != 16) {
  217. throw new Exception("Key长度不是16位");
  218. }
  219. // 判断采用DES加解密方式的Key是否为8位
  220. if (Algorithm.equals("DES") && sKey.length() != 8) {
  221. throw new Exception("Key长度不是8位");
  222. }
  223. byte[] raw = sKey.getBytes("ASCII");
  224. SecretKeySpec skeySpec = new SecretKeySpec(raw, Algorithm);
  225. Cipher cipher = Cipher.getInstance(Algorithm);
  226. cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
  227. byte[] encrypted = cipher.doFinal(sSrc.getBytes());
  228. return byte2hex(encrypted);
  229. }
  230. /**
  231. * 采用DES随机生成的密钥进行加密
  232. * @param key
  233. * @param info
  234. * @return
  235. */
  236. public String encryptToDES(SecretKey key, String info) {
  237. return encrypt("DES", key, info);
  238. }
  239. /**
  240. * 采用DES指定密钥的方式进行加密
  241. * @param key
  242. * @param info
  243. * @return
  244. * @throws Exception
  245. */
  246. public String encryptToDES(String key, String info) throws Exception {
  247. return encrypt("DES", info, key);
  248. }
  249. /**
  250. * 采用DES随机生成密钥的方式进行解密,密钥需要与加密的生成的密钥一样
  251. * @param key
  252. * @param sInfo
  253. * @return
  254. */
  255. public String decryptByDES(SecretKey key, String sInfo) {
  256. return decrypt("DES", key, sInfo);
  257. }
  258. /**
  259. * 采用DES用户指定密钥的方式进行解密,密钥需要与加密时指定的密钥一样
  260. * @param key
  261. * @param sInfo
  262. * @return
  263. */
  264. public String decryptByDES(String key, String sInfo) throws Exception {
  265. return decrypt("DES", sInfo, key);
  266. }
  267. /**
  268. * 采用AES随机生成的密钥进行加密
  269. * @param key
  270. * @param info
  271. * @return
  272. */
  273. public String encryptToAES(SecretKey key, String info) {
  274. return encrypt("AES", key, info);
  275. }
  276. /**
  277. * 采用AES指定密钥的方式进行加密
  278. * @param key
  279. * @param info
  280. * @return
  281. * @throws Exception
  282. */
  283. public String encryptToAES(String key, String info) throws Exception {
  284. return encrypt("AES", info, key);
  285. }
  286. /**
  287. * 采用AES随机生成密钥的方式进行解密,密钥需要与加密的生成的密钥一样
  288. * @param key
  289. * @param sInfo
  290. * @return
  291. */
  292. public String decryptByAES(SecretKey key, String sInfo) {
  293. return decrypt("AES", key, sInfo);
  294. }
  295. /**
  296. * 采用AES用户指定密钥的方式进行解密,密钥需要与加密时指定的密钥一样
  297. * @param key
  298. * @param sInfo
  299. * @return
  300. */
  301. public String decryptByAES(String key, String sInfo) throws Exception {
  302. return decrypt("AES", sInfo, key);
  303. }
  304. /**
  305. * 十六进制字符串转化为2进制
  306. *
  307. * @param hex
  308. * @return
  309. */
  310. public static byte[] hex2byte(String strhex) {
  311. if (strhex == null) {
  312. return null;
  313. }
  314. int l = strhex.length();
  315. if (l % 2 == 1) {
  316. return null;
  317. }
  318. byte[] b = new byte[l / 2];
  319. for (int i = 0; i != l / 2; i++) {
  320. b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2), 16);
  321. }
  322. return b;
  323. }
  324. /**
  325. * 将二进制转化为16进制字符串
  326. *
  327. * @param b 二进制字节数组
  328. * @return String
  329. */
  330. public static String byte2hex(byte[] b) {
  331. String hs = "";
  332. String stmp = "";
  333. for (int n = 0; n < b.length; n++) {
  334. stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
  335. if (stmp.length() == 1) {
  336. hs = hs + "0" + stmp;
  337. } else {
  338. hs = hs + stmp;
  339. }
  340. }
  341. return hs.toUpperCase();
  342. }
  343. /**
  344. * 测试
  345. *
  346. * @param args
  347. */
  348. public static void main(String[] args) {
  349. EncryptUtils encryptUtils = new EncryptUtils();
  350. String source = "www.putiman.com";
  351. System.out.println("Hello经过MD5:" + encryptUtils.encryptToMD5(source));
  352. System.out.println("Hello经过SHA:" + encryptUtils.encryptToSHA(source));
  353. System.out.println("========随机生成Key进行加解密==============");
  354. // 生成一个DES算法的密匙
  355. SecretKey key = encryptUtils.createSecretDESKey();
  356. String str1 = encryptUtils.encryptToDES(key, source);
  357. System.out.println("DES加密后为:" + str1);
  358. // 使用这个密匙解密
  359. String str2 = encryptUtils.decryptByDES(key, str1);
  360. System.out.println("DES解密后为:" + str2);
  361. // 生成一个AES算法的密匙
  362. SecretKey key1 = encryptUtils.createSecretAESKey();
  363. String stra = encryptUtils.encryptToAES(key1, source);
  364. System.out.println("AES加密后为:" + stra);
  365. // 使用这个密匙解密
  366. String strb = encryptUtils.decryptByAES(key1, stra);
  367. System.out.println("AES解密后为:" + strb);
  368. System.out.println("========指定Key进行加解密==============");
  369. try {
  370. String AESKey = encryptUtils.getAESKey(encryptUtils.encryptToSHA(source));
  371. String DESKey = encryptUtils.getDESKey(encryptUtils.encryptToSHA(source));
  372. System.out.println(AESKey);
  373. System.out.println(DESKey);
  374. String str11 = encryptUtils.encryptToDES(DESKey, source);
  375. System.out.println("DES加密后为:" + str11);
  376. // 使用这个密匙解密
  377. String str12 = encryptUtils.decryptByDES(DESKey, str11);
  378. System.out.println("DES解密后为:" + str12);
  379. // 生成一个AES算法的密匙
  380. String strc = encryptUtils.encryptToAES(AESKey, source);
  381. System.out.println("AES加密后为:" + strc);
  382. // 使用这个密匙解密
  383. String strd = encryptUtils.decryptByAES(AESKey, strc);
  384. System.out.println("AES解密后为:" + strd);
  385. } catch (Exception e) {
  386. e.printStackTrace();
  387. }
  388. }
  389. }
 

更多文章见:http://www.16boke.com

上一篇:WPF中嵌入Office编辑器(支持Word、Excel、PPT、Visio等)


下一篇:We Chall-Training: Get Sourced-Writeup