encoding.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package util
  2. import (
  3. "crypto/hmac"
  4. "crypto/md5"
  5. "crypto/rand"
  6. "crypto/sha256"
  7. "encoding/base64"
  8. "encoding/hex"
  9. "errors"
  10. "hash"
  11. "strings"
  12. )
  13. // GetRandomString generate random string by specify chars.
  14. // source: https://github.com/gogits/gogs/blob/9ee80e3e5426821f03a4e99fad34418f5c736413/modules/base/tool.go#L58
  15. func GetRandomString(n int, alphabets ...byte) string {
  16. const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  17. var bytes = make([]byte, n)
  18. rand.Read(bytes)
  19. for i, b := range bytes {
  20. if len(alphabets) == 0 {
  21. bytes[i] = alphanum[b%byte(len(alphanum))]
  22. } else {
  23. bytes[i] = alphabets[b%byte(len(alphabets))]
  24. }
  25. }
  26. return string(bytes)
  27. }
  28. // EncodePassword encodes a password using PBKDF2.
  29. func EncodePassword(password string, salt string) string {
  30. newPasswd := PBKDF2([]byte(password), []byte(salt), 10000, 50, sha256.New)
  31. return hex.EncodeToString(newPasswd)
  32. }
  33. // EncodeMd5 encodes a string to md5 hex value.
  34. func EncodeMd5(str string) string {
  35. m := md5.New()
  36. m.Write([]byte(str))
  37. return hex.EncodeToString(m.Sum(nil))
  38. }
  39. // PBKDF2 implements Password-Based Key Derivation Function 2), aimed to reduce
  40. // the vulnerability of encrypted keys to brute force attacks.
  41. // http://code.google.com/p/go/source/browse/pbkdf2/pbkdf2.go?repo=crypto
  42. func PBKDF2(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
  43. prf := hmac.New(h, password)
  44. hashLen := prf.Size()
  45. numBlocks := (keyLen + hashLen - 1) / hashLen
  46. var buf [4]byte
  47. dk := make([]byte, 0, numBlocks*hashLen)
  48. U := make([]byte, hashLen)
  49. for block := 1; block <= numBlocks; block++ {
  50. // N.B.: || means concatenation, ^ means XOR
  51. // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
  52. // U_1 = PRF(password, salt || uint(i))
  53. prf.Reset()
  54. prf.Write(salt)
  55. buf[0] = byte(block >> 24)
  56. buf[1] = byte(block >> 16)
  57. buf[2] = byte(block >> 8)
  58. buf[3] = byte(block)
  59. prf.Write(buf[:4])
  60. dk = prf.Sum(dk)
  61. T := dk[len(dk)-hashLen:]
  62. copy(U, T)
  63. // U_n = PRF(password, U_(n-1))
  64. for n := 2; n <= iter; n++ {
  65. prf.Reset()
  66. prf.Write(U)
  67. U = U[:0]
  68. U = prf.Sum(U)
  69. for x := range U {
  70. T[x] ^= U[x]
  71. }
  72. }
  73. }
  74. return dk[:keyLen]
  75. }
  76. // GetBasicAuthHeader returns a base64 encoded string from user and password.
  77. func GetBasicAuthHeader(user string, password string) string {
  78. var userAndPass = user + ":" + password
  79. return "Basic " + base64.StdEncoding.EncodeToString([]byte(userAndPass))
  80. }
  81. // DecodeBasicAuthHeader decodes user and password from a basic auth header.
  82. func DecodeBasicAuthHeader(header string) (string, string, error) {
  83. var code string
  84. parts := strings.SplitN(header, " ", 2)
  85. if len(parts) == 2 && parts[0] == "Basic" {
  86. code = parts[1]
  87. }
  88. decoded, err := base64.StdEncoding.DecodeString(code)
  89. if err != nil {
  90. return "", "", err
  91. }
  92. userAndPass := strings.SplitN(string(decoded), ":", 2)
  93. if len(userAndPass) != 2 {
  94. return "", "", errors.New("Invalid basic auth header")
  95. }
  96. return userAndPass[0], userAndPass[1], nil
  97. }
  98. // RandomHex returns a random string from a n seed.
  99. func RandomHex(n int) (string, error) {
  100. bytes := make([]byte, n)
  101. if _, err := rand.Read(bytes); err != nil {
  102. return "", err
  103. }
  104. return hex.EncodeToString(bytes), nil
  105. }