加密
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

139 lines
2.8 KiB

3 years ago
  1. package crypter
  2. import (
  3. "crypto/md5"
  4. "encoding/base64"
  5. "fmt"
  6. "io"
  7. "strconv"
  8. "strings"
  9. "time"
  10. )
  11. // SSO gxytoken authcode
  12. // btype 加密or解密 bool true:加密 false:解密 默认false
  13. // skey 秘钥
  14. // text 加/解密内容
  15. func AuthCode(text, skey string, btype bool) string {
  16. isEncode := btype
  17. key := skey
  18. expiry := 0
  19. cKeyLen := 4
  20. timestamp := time.Now().Unix()
  21. // md5加密key
  22. mKey := Md5Sum(key)
  23. // 参与加密的
  24. keyA := Md5Sum(mKey[0:16])
  25. // 用于验证数据有效性的
  26. keyB := Md5Sum(mKey[16:])
  27. // 动态部分
  28. var keyC string
  29. if cKeyLen > 0 {
  30. if isEncode {
  31. // 加密的时候,动态获取一个秘钥
  32. keyC = Md5Sum(fmt.Sprint(timestamp))[32-cKeyLen:]
  33. } else {
  34. // 解密的时候从头部获取动态秘钥部分
  35. keyC = text[0:cKeyLen]
  36. }
  37. }
  38. // 加入了动态的秘钥
  39. cryptKey := keyA + Md5Sum(keyA+keyC)
  40. // 秘钥长度
  41. keyLen := len(cryptKey)
  42. if isEncode {
  43. // 加密 前10位是过期验证字符串 10-26位字符串验证
  44. var d int64
  45. if expiry > 0 {
  46. d = timestamp + int64(expiry)
  47. }
  48. text = fmt.Sprintf("%010d%s%s", d, Md5Sum(text + keyB)[0:16], text)
  49. } else {
  50. // 解密
  51. //res, _ := base64.StdEncoding.DecodeString(text[cKeyLen:])
  52. res := Base64Decode(text[cKeyLen:])
  53. text = string(res)
  54. }
  55. // 字符串长度
  56. textLen := len(text)
  57. if textLen <= 0 {
  58. return ""
  59. }
  60. // 密匙簿(0-256)
  61. box := make([]int, 0)
  62. for i := 0; i < 256; i++ {
  63. box = append(box, i)
  64. }
  65. // 对称算法
  66. var rndKey []int
  67. cryptKeyB := []byte(cryptKey)
  68. for i := 0; i < 256; i++ {
  69. pos := i % keyLen
  70. rndKey = append(rndKey, int(cryptKeyB[pos]))
  71. }
  72. j := 0
  73. for i := 0; i < 256; i++ {
  74. j = (j + box[i] + rndKey[i]) % 256
  75. box[i], box[j] = box[j], box[i]
  76. }
  77. textB := []byte(text)
  78. a := 0
  79. j = 0
  80. var result []byte
  81. for i := 0; i < textLen; i++ {
  82. a = (a + 1) % 256
  83. j = (j + box[a]) % 256
  84. box[a], box[j] = box[j], box[a]
  85. result = append(result, byte(int(textB[i])^(box[(box[a]+box[j])%256])))
  86. }
  87. if isEncode {
  88. return keyC + strings.Replace(base64.StdEncoding.EncodeToString(result), "=", "", -1)
  89. }
  90. // 获取前10位,判断过期时间
  91. d, err := strconv.ParseInt(string(result[0:10]), 10, 64)
  92. if err != nil {
  93. d = 0
  94. }
  95. fmt.Println(string(result[10:26]), Md5Sum(string(result[26:]) + keyB)[0:16])
  96. if (d == 0 || d-timestamp > 0) && string(result[10:26]) == Md5Sum(string(result[26:]) + keyB)[0:16] {
  97. return string(result[26:])
  98. }
  99. fmt.Println(string(result[26:]))
  100. return ""
  101. }
  102. //MD5SUm
  103. func Md5Sum(str string) string {
  104. h := md5.New()
  105. io.WriteString(h, str)
  106. return fmt.Sprintf("%x", h.Sum(nil))
  107. }
  108. //Base64Decode
  109. func Base64Decode(str string) []byte {
  110. var sdec []byte
  111. var err error
  112. x := len(str) * 3 % 4
  113. fmt.Println(x)
  114. switch {
  115. case x == 2:
  116. str += "=="
  117. case x == 1:
  118. str += "="
  119. }
  120. if sdec, err = base64.StdEncoding.DecodeString(str); err != nil {
  121. return sdec
  122. }
  123. return sdec
  124. }