password.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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. saltSecret, err := salt_secret()
  23. if err != nil {
  24. return "", err
  25. }
  26. salt, err := salt(salt_local_secret + saltSecret)
  27. if err != nil {
  28. return "", err
  29. }
  30. interation := randInt(1, 20)
  31. hash, err := hash(pass, saltSecret, salt, int64(interation))
  32. if err != nil {
  33. return "", err
  34. }
  35. interationString := strconv.Itoa(interation)
  36. password := saltSecret + delmiter + interationString + delmiter + hash + delmiter + salt
  37. return password, nil
  38. }
  39. //校验密码是否有效
  40. func PasswordVerify(hashing string, pass string) (bool, error) {
  41. data := trimSaltHash(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 passSalt = salt_secret + pass + salt + salt_secret + pass + salt + pass + pass + salt
  55. var i int
  56. hashPass := salt_local_secret
  57. hashStart := sha512.New()
  58. hashCenter := sha256.New()
  59. hashOutput := sha256.New224()
  60. i = 0
  61. for i <= stretching_password {
  62. i = i + 1
  63. _, err := hashStart.Write([]byte(passSalt + hashPass))
  64. if err != nil {
  65. return "", err
  66. }
  67. hashPass = hex.EncodeToString(hashStart.Sum(nil))
  68. }
  69. i = 0
  70. for int64(i) <= interation {
  71. i = i + 1
  72. hashPass = hashPass + hashPass
  73. }
  74. i = 0
  75. for i <= stretching_password {
  76. i = i + 1
  77. _, err := hashCenter.Write([]byte(hashPass + salt_secret))
  78. if err != nil {
  79. return "", err
  80. }
  81. hashPass = hex.EncodeToString(hashCenter.Sum(nil))
  82. }
  83. if _,err := hashOutput.Write([]byte(hashPass + salt_local_secret)); err != nil {
  84. return "", err
  85. }
  86. hashPass = hex.EncodeToString(hashOutput.Sum(nil))
  87. return hashPass, nil
  88. }
  89. func trimSaltHash(hash string) map[string]string {
  90. str := strings.Split(hash, delmiter)
  91. return map[string]string{
  92. "salt_secret": str[0],
  93. "interation_string": str[1],
  94. "hash": str[2],
  95. "salt": str[3],
  96. }
  97. }
  98. func salt(secret string) (string, error) {
  99. buf := make([]byte, saltSize, saltSize+md5.Size)
  100. _, err := io.ReadFull(rand.Reader, buf)
  101. if err != nil {
  102. return "", err
  103. }
  104. hash := md5.New()
  105. hash.Write(buf)
  106. hash.Write([]byte(secret))
  107. return hex.EncodeToString(hash.Sum(buf)), nil
  108. }
  109. func salt_secret() (string, error) {
  110. rb := make([]byte, randInt(10, 100))
  111. _, err := rand.Read(rb)
  112. if err != nil {
  113. return "", err
  114. }
  115. return base64.URLEncoding.EncodeToString(rb), nil
  116. }
  117. func randInt(min int, max int) int {
  118. return min + mt.Intn(max-min)
  119. }