SHA.java 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. package com.happy.common.http;
  2. import org.apache.commons.codec.binary.Hex;
  3. import org.apache.commons.lang3.Validate;
  4. import java.security.GeneralSecurityException;
  5. import java.security.MessageDigest;
  6. import java.security.SecureRandom;
  7. import java.util.Random;
  8. public class SHA {
  9. private static SecureRandom random = new SecureRandom();
  10. /**
  11. * 加密遵循RFC2671规范 将相关参数加密生成一个MD5字符串,并返回
  12. */
  13. public static String http_da_calc_HA1(String username, String realm, String password,
  14. String nonce, String nc, String cnonce, String qop,
  15. String method, String uri, String algorithm) {
  16. String HA1, HA2;
  17. if ("SHA-256".equals(algorithm)) {
  18. HA1 = HA1_MD5(username, realm, password);
  19. } else {
  20. HA1 = HA1_MD5_sess(username, realm, password, nonce, cnonce);
  21. }
  22. byte[] sha256Byte = sha256(HA1.getBytes());
  23. HA1 = new String(Hex.encodeHex(sha256Byte));
  24. sha256Byte = sha256(HA2(method, uri).getBytes());
  25. HA2 = new String(Hex.encodeHex(sha256Byte));
  26. String original = HA1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + HA2;
  27. sha256Byte = sha256(original.getBytes());
  28. return new String(Hex.encodeHex(sha256Byte));
  29. }
  30. /**
  31. * algorithm值为MD5时规则
  32. */
  33. private static String HA1_MD5(String username, String realm, String password) {
  34. String s1 = username + ":" + realm + ":" + password;
  35. return s1;
  36. }
  37. /**
  38. * algorithm值为MD5-sess时规则
  39. */
  40. private static String HA1_MD5_sess(String username, String realm, String password, String nonce, String cnonce) {
  41. // MD5(username:realm:password):nonce:cnonce
  42. String s = HA1_MD5(username, realm, password);
  43. byte[] md5Byte = sha256(s.getBytes());
  44. String smd5 = new String(Hex.encodeHex(md5Byte));
  45. return smd5 + ":" + nonce + ":" + cnonce;
  46. }
  47. private static String HA2(String method, String uri) {
  48. String s2 = method + ":" + uri;
  49. return s2;
  50. }
  51. /**
  52. * 对输入字符串进行md5散列.
  53. */
  54. public static byte[] sha256(byte[] input) {
  55. return digest(input, "sha-256", null, 1);
  56. }
  57. /**
  58. * 对字符串进行散列, 支持md5与sha1算法.
  59. */
  60. private static byte[] digest(byte[] input, String algorithm, byte[] salt, int iterations) {
  61. try {
  62. MessageDigest digest = MessageDigest.getInstance(algorithm);
  63. if (salt != null) {
  64. digest.update(salt);
  65. }
  66. byte[] result = digest.digest(input);
  67. for (int i = 1; i < iterations; i++) {
  68. digest.reset();
  69. result = digest.digest(result);
  70. }
  71. return result;
  72. } catch (GeneralSecurityException e) {
  73. throw new RuntimeException(e);
  74. }
  75. }
  76. /**
  77. * 随机生成numBytes长度数组
  78. * @param numBytes
  79. * @return
  80. */
  81. public static byte[] generateSalt(int numBytes) {
  82. Validate.isTrue(numBytes > 0, "numBytes argument must be a positive integer (1 or larger)", (long) numBytes);
  83. byte[] bytes = new byte[numBytes];
  84. random.nextBytes(bytes);
  85. return bytes;
  86. }
  87. @Deprecated
  88. public static String generateSalt2(int length) {
  89. String val = "";
  90. Random random = new Random();
  91. //参数length,表示生成几位随机数
  92. for (int i = 0; i < length; i++) {
  93. String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
  94. //输出字母还是数字
  95. if ("char".equalsIgnoreCase(charOrNum)) {
  96. //输出是大写字母还是小写字母
  97. int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
  98. val += (char) (random.nextInt(26) + temp);
  99. } else if ("num".equalsIgnoreCase(charOrNum)) {
  100. val += String.valueOf(random.nextInt(10));
  101. }
  102. }
  103. return val.toLowerCase();
  104. }
  105. public static void main(String[] args) {
  106. String response = http_da_calc_HA1("admin","device","Chuanghai-2021",
  107. "58cacbc8f220d14fae8c8d8800c00fc4d424936c49d229872e86e7dbcd9b9a6e","00000001",
  108. "247fe9fd623c1c42","auth","POST","/API/Web/Login","SHA-256");
  109. System.out.println(response);
  110. }
  111. }