encoding.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package util
  2. import (
  3. "crypto/hmac"
  4. "crypto/md5"
  5. "crypto/rand"
  6. "crypto/sha256"
  7. "encoding/hex"
  8. "fmt"
  9. "hash"
  10. )
  11. // source: https://github.com/gogits/gogs/blob/9ee80e3e5426821f03a4e99fad34418f5c736413/modules/base/tool.go#L58
  12. func GetRandomString(n int, alphabets ...byte) string {
  13. const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  14. var bytes = make([]byte, n)
  15. rand.Read(bytes)
  16. for i, b := range bytes {
  17. if len(alphabets) == 0 {
  18. bytes[i] = alphanum[b%byte(len(alphanum))]
  19. } else {
  20. bytes[i] = alphabets[b%byte(len(alphabets))]
  21. }
  22. }
  23. return string(bytes)
  24. }
  25. func EncodePassword(password string, salt string) string {
  26. newPasswd := PBKDF2([]byte(password), []byte(salt), 10000, 50, sha256.New)
  27. return fmt.Sprintf("%x", newPasswd)
  28. }
  29. // Encode string to md5 hex value.
  30. func EncodeMd5(str string) string {
  31. m := md5.New()
  32. m.Write([]byte(str))
  33. return hex.EncodeToString(m.Sum(nil))
  34. }
  35. // http://code.google.com/p/go/source/browse/pbkdf2/pbkdf2.go?repo=crypto
  36. func PBKDF2(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte {
  37. prf := hmac.New(h, password)
  38. hashLen := prf.Size()
  39. numBlocks := (keyLen + hashLen - 1) / hashLen
  40. var buf [4]byte
  41. dk := make([]byte, 0, numBlocks*hashLen)
  42. U := make([]byte, hashLen)
  43. for block := 1; block <= numBlocks; block++ {
  44. // N.B.: || means concatenation, ^ means XOR
  45. // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter
  46. // U_1 = PRF(password, salt || uint(i))
  47. prf.Reset()
  48. prf.Write(salt)
  49. buf[0] = byte(block >> 24)
  50. buf[1] = byte(block >> 16)
  51. buf[2] = byte(block >> 8)
  52. buf[3] = byte(block)
  53. prf.Write(buf[:4])
  54. dk = prf.Sum(dk)
  55. T := dk[len(dk)-hashLen:]
  56. copy(U, T)
  57. // U_n = PRF(password, U_(n-1))
  58. for n := 2; n <= iter; n++ {
  59. prf.Reset()
  60. prf.Write(U)
  61. U = U[:0]
  62. U = prf.Sum(U)
  63. for x := range U {
  64. T[x] ^= U[x]
  65. }
  66. }
  67. }
  68. return dk[:keyLen]
  69. }