password.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package utils
  2. import (
  3. "crypto/md5"
  4. "crypto/rand"
  5. "crypto/sha256"
  6. "crypto/sha512"
  7. "encoding/base64"
  8. "encoding/hex"
  9. "io"
  10. mt "math/rand"
  11. "strconv"
  12. "strings"
  13. )
  14. const (
  15. saltSize = 16
  16. delmiter = "$"
  17. stretching_password = 500
  18. salt_local_secret = "ahfw*&TGdsfnbi*^Wt"
  19. )
  20. //加密密码
  21. func PasswordHash(pass string) (string, error) {
  22. salt_secret, err := salt_secret()
  23. if err != nil {
  24. return "", err
  25. }
  26. salt, err := salt(salt_local_secret + salt_secret)
  27. if err != nil {
  28. return "", err
  29. }
  30. interation := randInt(1, 20)
  31. hash, err := hash(pass, salt_secret, salt, int64(interation))
  32. if err != nil {
  33. return "", err
  34. }
  35. interation_string := strconv.Itoa(interation)
  36. password := salt_secret + delmiter + interation_string + delmiter + hash + delmiter + salt
  37. return password, nil
  38. }
  39. //校验密码是否有效
  40. func PasswordVerify(hashing string, pass string) (bool, error) {
  41. data := trim_salt_hash(hashing)
  42. interation, _ := strconv.ParseInt(data["interation_string"], 10, 64)
  43. has, err := hash(pass, data["salt_secret"], data["salt"], int64(interation))
  44. if err != nil {
  45. return false, err
  46. }
  47. if (data["salt_secret"] + delmiter + data["interation_string"] + delmiter + has + delmiter + data["salt"]) == hashing {
  48. return true, nil
  49. } else {
  50. return false, nil
  51. }
  52. }
  53. func hash(pass string, salt_secret string, salt string, interation int64) (string, error) {
  54. var pass_salt string = salt_secret + pass + salt + salt_secret + pass + salt + pass + pass + salt
  55. var i int
  56. hash_pass := salt_local_secret
  57. hash_start := sha512.New()
  58. hash_center := sha256.New()
  59. hash_output := sha256.New224()
  60. i = 0
  61. for i <= stretching_password {
  62. i = i + 1
  63. hash_start.Write([]byte(pass_salt + hash_pass))
  64. hash_pass = hex.EncodeToString(hash_start.Sum(nil))
  65. }
  66. i = 0
  67. for int64(i) <= interation {
  68. i = i + 1
  69. hash_pass = hash_pass + hash_pass
  70. }
  71. i = 0
  72. for i <= stretching_password {
  73. i = i + 1
  74. hash_center.Write([]byte(hash_pass + salt_secret))
  75. hash_pass = hex.EncodeToString(hash_center.Sum(nil))
  76. }
  77. hash_output.Write([]byte(hash_pass + salt_local_secret))
  78. hash_pass = hex.EncodeToString(hash_output.Sum(nil))
  79. return hash_pass, nil
  80. }
  81. func trim_salt_hash(hash string) map[string]string {
  82. str := strings.Split(hash, delmiter)
  83. return map[string]string{
  84. "salt_secret": str[0],
  85. "interation_string": str[1],
  86. "hash": str[2],
  87. "salt": str[3],
  88. }
  89. }
  90. func salt(secret string) (string, error) {
  91. buf := make([]byte, saltSize, saltSize+md5.Size)
  92. _, err := io.ReadFull(rand.Reader, buf)
  93. if err != nil {
  94. return "", err
  95. }
  96. hash := md5.New()
  97. hash.Write(buf)
  98. hash.Write([]byte(secret))
  99. return hex.EncodeToString(hash.Sum(buf)), nil
  100. }
  101. func salt_secret() (string, error) {
  102. rb := make([]byte, randInt(10, 100))
  103. _, err := rand.Read(rb)
  104. if err != nil {
  105. return "", err
  106. }
  107. return base64.URLEncoding.EncodeToString(rb), nil
  108. }
  109. func randInt(min int, max int) int {
  110. return min + mt.Intn(max-min)
  111. }