encoding.go 1.7 KB

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