在路上

 找回密码
 立即注册
在路上 站点首页 学习 查看内容

详解Java中实现SHA1与MD5加密算法的基本方法

2016-8-29 13:19| 发布者: zhangjf| 查看: 695| 评论: 0

摘要: SHA1 package com.stone.security; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.DigestInputStream; im ...

SHA1

  1. package com.stone.security;
  2. import java.io.ByteArrayInputStream;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.security.DigestInputStream;
  7. import java.security.DigestOutputStream;
  8. import java.security.MessageDigest;
  9. import java.util.Arrays;
  10. import javax.crypto.Mac;
  11. import javax.crypto.SecretKey;
  12. import javax.crypto.SecretKeyFactory;
  13. import javax.crypto.spec.PBEKeySpec;
  14. public class SHA {
  15. public static void main(String[] args) throws Exception {
  16. encodeByMAC("中国oP……&*()…&802134…");
  17. encodeBySHA("中国oP……&*()…&802134…");
  18. shaFile();
  19. }
  20. /**
  21. * 使用MAC 算法的 消息摘要
  22. * @param data
  23. * @throws Exception
  24. */
  25. public static void encodeByMAC(String data) throws Exception{
  26. // KeyGenerator keyGen = KeyGenerator.getInstance("HmacSHA1");
  27. // SecretKey key = keyGen.generateKey(); //这个每次生成的key不一样, 此处不能使用
  28. PBEKeySpec keySpec = new PBEKeySpec("randomkey^(^&*^%$".toCharArray());
  29. SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
  30. SecretKey key = keyFactory.generateSecret(keySpec);
  31. /*
  32. * 此类提供“消息验证码”(Message Authentication Code,MAC)算法的功能。
  33. * MAC 基于秘密密钥提供一种方式来检查在不可靠介质上进行传输或存储的信息的完整性。
  34. * 通常,消息验证码在共享秘密密钥的两个参与者之间使用,以验证这两者之间传输的信息。
  35. * 基于加密哈希函数的 MAC 机制也叫作 HMAC。结合秘密共享密钥,
  36. * HMAC 可以用于任何加密哈希函数(如 MD5 或 SHA-1)
  37. */
  38. Mac mac = Mac.getInstance("HmacSHA1");
  39. //以下三种都可用
  40. // Mac mac = Mac.getInstance("HmacSHA256");
  41. // Mac mac = Mac.getInstance("HmacSHA384");
  42. // Mac mac = Mac.getInstance("HmacSHA512");
  43. mac.init(key);
  44. byte[] dest = mac.doFinal(data.getBytes());
  45. System.out.println(dest.length);
  46. System.out.println("MAC摘要:" + Arrays.toString(dest));
  47. }
  48. /**
  49. * SHA1加密 使用消息摘要MessageDigest 处理
  50. * @throws Exception
  51. */
  52. public static String encodeBySHA(String str) throws Exception{
  53. MessageDigest sha1;
  54. sha1 = MessageDigest.getInstance("SHA1");
  55. //以下三种不可用
  56. // sha1 = MessageDigest.getInstance("SHA256");
  57. // sha1 = MessageDigest.getInstance("SHA384");
  58. // sha1 = MessageDigest.getInstance("SHA512");
  59. sha1.update(str.getBytes()); //先更新摘要
  60. byte[] digest = sha1.digest(); //再通过执行诸如填充之类的最终操作完成哈希计算。在调用此方法之后,摘要被重置。
  61. /*
  62. * 使用指定的 byte 数组对摘要进行最后更新,然后完成摘要计算。
  63. * 也就是说,此方法首先调用 update(input),
  64. * 向 update 方法传递 input 数组,然后调用 digest()。
  65. */
  66. // byte[] digest = sha1.digest(str.getBytes());
  67. String hex = toHex(digest);
  68. System.out.println("SHA1摘要:" + hex);
  69. return hex;
  70. }
  71. /**
  72. * 文件数据摘要
  73. * @throws Exception
  74. */
  75. public static void shaFile() throws Exception {
  76. MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
  77. DigestOutputStream dos = new DigestOutputStream(new FileOutputStream(new File("abc.txt")), messageDigest);
  78. dos.write("中华人民……&())f*(214)admin*".getBytes());
  79. dos.close();
  80. byte[] digest = messageDigest.digest();
  81. System.out.println("使用流写文件,该文件的摘要为:" + toHex(digest));
  82. DigestInputStream dis = new DigestInputStream(new FileInputStream(new File("abc.txt")), messageDigest);
  83. byte[] buf = new byte[100];
  84. int len;
  85. while ((len = dis.read(buf)) != -1) {
  86. System.out.println("读取到的数据为:" + new String(buf, 0, len));
  87. }
  88. dis.close();
  89. byte[] digest2 = messageDigest.digest();
  90. //当流读取完毕,即将文件读完了, 这时的摘要 才与 写入时的 一样
  91. System.out.println("使用流读文件,该文件的摘要为:" + toHex(digest2));
  92. }
  93. /**
  94. * sha1 摘要转16进制
  95. * @param digest
  96. * @return
  97. */
  98. private static String toHex(byte[] digest) {
  99. StringBuilder sb = new StringBuilder();
  100. int len = digest.length;
  101. String out = null;
  102. for (int i = 0; i < len; i++) {
  103. // out = Integer.toHexString(0xFF & digest[i] + 0xABCDEF); //加任意 salt
  104. out = Integer.toHexString(0xFF & digest[i]);//原始方法
  105. if (out.length() == 1) {
  106. sb.append("0");//如果为1位 前面补个0
  107. }
  108. sb.append(out);
  109. }
  110. return sb.toString();
  111. }
  112. }
复制代码


MD5

MD5(Message Digest Algorithm 5),即消息摘要算法第五版。消息摘要是一种算法:无论原始数据多长,消息摘要的结果都是固定长度的;是一种不可逆的算法
原始数据任意bit位的变化,都会导致消息摘要的结果有很大的不同,且根据结果推算出原始数据的概率极低。
消息摘要可以看作原始数据的指纹,指纹不同则原始数据不同。

  1. package com.stone.security;
  2. import java.io.ByteArrayInputStream;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.security.DigestInputStream;
  7. import java.security.DigestOutputStream;
  8. import java.security.MessageDigest;
  9. import java.util.Arrays;
  10. import javax.crypto.Mac;
  11. import javax.crypto.SecretKey;
  12. import javax.crypto.SecretKeyFactory;
  13. import javax.crypto.spec.PBEKeySpec;
  14. public class MD5 {
  15. public static void main(String[] args) throws Exception {
  16. encodeByMAC("中国oP……&*()…&802134…");
  17. encodeByMd5("中国oP……&*()…&802134…");
  18. md5File();
  19. }
  20. /**
  21. * 使用MAC 算法的 消息摘要
  22. * @param data
  23. * @throws Exception
  24. */
  25. public static void encodeByMAC(String data) throws Exception{
  26. // KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
  27. // SecretKey key = keyGen.generateKey(); //这个每次生成的key不一样, 此处不能使用
  28. PBEKeySpec keySpec = new PBEKeySpec("randomkey^(^&*^%$".toCharArray());
  29. SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
  30. SecretKey key = keyFactory.generateSecret(keySpec);
  31. /*
  32. * 此类提供“消息验证码”(Message Authentication Code,MAC)算法的功能。
  33. * MAC 基于秘密密钥提供一种方式来检查在不可靠介质上进行传输或存储的信息的完整性。
  34. * 通常,消息验证码在共享秘密密钥的两个参与者之间使用,以验证这两者之间传输的信息。
  35. * 基于加密哈希函数的 MAC 机制也叫作 HMAC。结合秘密共享密钥,
  36. * HMAC 可以用于任何加密哈希函数(如 MD5 或 SHA-1)
  37. */
  38. Mac mac = Mac.getInstance("HmacMD5");
  39. mac.init(key);
  40. byte[] dest = mac.doFinal(data.getBytes());
  41. System.out.println(dest.length);
  42. System.out.println("MAC摘要:" + Arrays.toString(dest));
  43. }
  44. /**
  45. * md5加密 使用消息摘要MessageDigest 处理
  46. * @throws Exception
  47. */
  48. public static String encodeByMd5(String str) throws Exception{
  49. MessageDigest md5;
  50. md5 = MessageDigest.getInstance("MD5");
  51. md5.update(str.getBytes()); //先更新摘要
  52. byte[] digest = md5.digest(); //再通过执行诸如填充之类的最终操作完成哈希计算。在调用此方法之后,摘要被重置。
  53. /*
  54. * 使用指定的 byte 数组对摘要进行最后更新,然后完成摘要计算。
  55. * 也就是说,此方法首先调用 update(input),
  56. * 向 update 方法传递 input 数组,然后调用 digest()。
  57. */
  58. // byte[] digest = md5.digest(str.getBytes());
  59. String hex = toHex(digest);
  60. System.out.println("MD5摘要:" + hex);
  61. return hex;
  62. }
  63. /**
  64. * 文件数据摘要
  65. * @throws Exception
  66. */
  67. public static void md5File() throws Exception {
  68. MessageDigest messageDigest = MessageDigest.getInstance("MD5");
  69. DigestOutputStream dos = new DigestOutputStream(new FileOutputStream(new File("abc.txt")), messageDigest);
  70. dos.write("中华人民……&())f*(214)admin*".getBytes());
  71. dos.close();
  72. byte[] digest = messageDigest.digest();
  73. System.out.println("使用流写文件,该文件的摘要为:" + toHex(digest));
  74. DigestInputStream dis = new DigestInputStream(new FileInputStream(new File("abc.txt")), messageDigest);
  75. byte[] buf = new byte[100];
  76. int len;
  77. while ((len = dis.read(buf)) != -1) {
  78. System.out.println("读取到的数据为:" + new String(buf, 0, len));
  79. }
  80. dis.close();
  81. byte[] digest2 = messageDigest.digest();
  82. //当流读取完毕,即将文件读完了, 这时的摘要 才与 写入时的 一样
  83. System.out.println("使用流读文件,该文件的摘要为:" + toHex(digest2));
  84. }
  85. /**
  86. * md5 摘要转16进制
  87. * @param digest
  88. * @return
  89. */
  90. private static String toHex(byte[] digest) {
  91. StringBuilder sb = new StringBuilder();
  92. int len = digest.length;
  93. String out = null;
  94. for (int i = 0; i < len; i++) {
  95. // out = Integer.toHexString(0xFF & digest[i] + 0xABCDEF); //加任意 salt
  96. out = Integer.toHexString(0xFF & digest[i]);//原始方法
  97. if (out.length() == 1) {
  98. sb.append("0");//如果为1位 前面补个0
  99. }
  100. sb.append(out);
  101. }
  102. return sb.toString();
  103. }
  104. }
复制代码

最新评论

小黑屋|在路上 ( 蜀ICP备15035742号-1 

;

GMT+8, 2025-7-6 22:07

Copyright 2015-2025 djqfx

返回顶部