reg-code.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. package utils
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "crypto/md5"
  6. "crypto/rand"
  7. "crypto/sha1"
  8. "encoding/base64"
  9. "errors"
  10. "fmt"
  11. "io"
  12. "strconv"
  13. "strings"
  14. "github.com/shirou/gopsutil/disk"
  15. "github.com/shirou/gopsutil/net"
  16. )
  17. // 字符串生成md5
  18. func CreatMD5(s string) string {
  19. data := []byte(s)
  20. has := md5.Sum(data)
  21. return fmt.Sprintf("%x", has)
  22. }
  23. func GetDiskId() string {
  24. partitions, err := disk.Partitions(false)
  25. if err != nil {
  26. return ""
  27. }
  28. return disk.GetDiskSerialNumber(partitions[0].Device)
  29. }
  30. // 获取物理网卡mac地址
  31. func GetRealMacAddr() string {
  32. netInterfaces, err := net.Interfaces()
  33. if err != nil {
  34. return ""
  35. }
  36. loindex := 0
  37. for _, netInterface := range netInterfaces {
  38. if netInterface.Name == "lo" {
  39. loindex = netInterface.Index
  40. break
  41. }
  42. }
  43. if len(netInterfaces) < loindex+1 {
  44. return ""
  45. }
  46. fmt.Println(netInterfaces[loindex].HardwareAddr)
  47. return netInterfaces[loindex].HardwareAddr
  48. }
  49. func GetDeviceId() string {
  50. // deviceId := fmt.Sprintf("%s:%s", GetRealMacAddr(), GetDiskId())
  51. deviceId := GetRealMacAddr()
  52. fmt.Println(deviceId)
  53. return CreatMD5(deviceId)
  54. }
  55. // sha1()方法,返回的是byte转换的字符串,如果需要转成16进制,可以使用hex.EncodeToString
  56. func GetSha1(str string) string {
  57. h := sha1.New()
  58. io.WriteString(h, str)
  59. return string(h.Sum(nil))
  60. }
  61. // 右边补全字符串实现方法,主要实现php的str_pad()方法
  62. func StrPadRight(input string, padLength int, padString string) string {
  63. output := ""
  64. inputLen := len(input)
  65. if inputLen >= padLength {
  66. return input
  67. }
  68. ll := padLength - inputLen
  69. for i := 1; i <= ll; i = i + len(padString) {
  70. output += padString
  71. }
  72. return input + output
  73. }
  74. // 生成密钥
  75. func GenSecretKey(appId string, appSecret string) (secretKey string) {
  76. key := appId + "&" + appSecret
  77. sha1_str := GetSha1(key)
  78. str10 := "0"
  79. pack64, _ := strconv.ParseUint(str10, 10, 32)
  80. fmt.Println(pack64)
  81. pack32 := uint32(pack64)
  82. str_pad := StrPadRight(sha1_str, 32, string(rune(pack32)))
  83. secretKey = base64.StdEncoding.EncodeToString([]byte(str_pad))
  84. return secretKey
  85. }
  86. // 解密
  87. func GetCallbackData(secretKey string, encryptData string) (result_str string, err error) {
  88. decodeSecretKeyByte, _ := base64.StdEncoding.DecodeString(secretKey)
  89. decodeSecretKey := string(decodeSecretKeyByte)
  90. orderSuccessPayInfoByte, err2 := DecodeAesGcm(encryptData, decodeSecretKey, "")
  91. result_str = string(orderSuccessPayInfoByte)
  92. if err2 != nil {
  93. return result_str, errors.New("decode error")
  94. }
  95. return result_str, err
  96. }
  97. // 加密
  98. func SetCallbackData(secretKey string, data string) (result_str string, err error) {
  99. decodeSecretKeyByte, _ := base64.StdEncoding.DecodeString(secretKey)
  100. decodeSecretKey := string(decodeSecretKeyByte)
  101. orderSuccessPayInfoByte, err2 := EncodeAesGcm(data, decodeSecretKey, "")
  102. result_str = string(orderSuccessPayInfoByte)
  103. if err2 != nil {
  104. return result_str, errors.New("encode error")
  105. }
  106. return result_str, err
  107. }
  108. // url安全模式decode字符串
  109. func UrlSafeB64decode(str string) (result []byte) {
  110. str = strings.Replace(str, "-", "+", -1)
  111. str = strings.Replace(str, "_", "/", -1)
  112. mod4 := len(str) % 4
  113. if mod4 != 0 {
  114. str = str + "===="[0:mod4]
  115. }
  116. result, _ = base64.StdEncoding.DecodeString(str)
  117. return result
  118. }
  119. // base64字符串,替换转换为安全模式
  120. func UrlSafeB64encode(str string) (result string) {
  121. str = strings.Replace(str, "+", "-", -1)
  122. str = strings.Replace(str, "/", "_", -1)
  123. return str
  124. }
  125. // 使用aes-256-gcm方式解密字符串
  126. func DecodeAesGcm(encryptData string, hex_key string, hex_add string) ([]byte, error) {
  127. tagSize := 16 //nonceSize,tag的长度,用于open时候生成tag,默认12
  128. key := []byte(hex_key)
  129. add := []byte(hex_add)
  130. block, err := aes.NewCipher(key) //生成加解密用的block
  131. if err != nil {
  132. return []byte(""), err
  133. }
  134. //根据不同加密算法,也有不同tag长度的方法设定和调用,比如NewGCMWithTagSize、newGCMWithNonceAndTagSize
  135. aesgcm, err := cipher.NewGCMWithNonceSize(block, tagSize)
  136. if err != nil {
  137. return []byte(""), err
  138. }
  139. decodeEncryptStr := UrlSafeB64decode(encryptData)
  140. ciphertext := decodeEncryptStr
  141. if len(ciphertext) <= aesgcm.NonceSize() { // 长度应该>iv
  142. return []byte(""), errors.New("string: too short") //解密失败
  143. }
  144. iv := ciphertext[:aesgcm.NonceSize()] //分离出IV
  145. ciphertext = ciphertext[aesgcm.NonceSize():] // 密文,tag是调用open方法时候通过密文和前面new时候传的size来进行截取的
  146. plaintext, err := aesgcm.Open(nil, iv, ciphertext, add)
  147. return plaintext, err
  148. }
  149. // 使用aes-256-gcm加密数据
  150. func EncodeAesGcm(data string, hex_key string, hex_add string) (result string, error error) {
  151. tagSize := 16 //nonceSize,tag的长度,用于open时候生成tag,默认12
  152. key := []byte(hex_key)
  153. add := []byte(hex_add)
  154. block, err := aes.NewCipher(key) //生成加解密用的block
  155. if err != nil {
  156. return result, err
  157. }
  158. //根据不同加密算法,也有不同tag长度的方法设定和调用,比如NewGCMWithTagSize、newGCMWithNonceAndTagSize
  159. aesgcm, err := cipher.NewGCMWithNonceSize(block, tagSize)
  160. if err != nil {
  161. return result, err
  162. }
  163. plaintext := []byte(data)
  164. iv := make([]byte, tagSize) // NonceSize=12
  165. rand.Read(iv) //获取随机值
  166. ciphertext := aesgcm.Seal(iv, iv, plaintext, add) //加密,密文为:iv+密文+tag
  167. result = base64.StdEncoding.EncodeToString(ciphertext)
  168. result = UrlSafeB64encode(result)
  169. return result, nil // 生成的BS64
  170. }