rsa.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package utils
  2. import (
  3. "crypto/hmac"
  4. "crypto/rand"
  5. "crypto/rsa"
  6. "crypto/sha256"
  7. "crypto/x509"
  8. "encoding/base64"
  9. "encoding/pem"
  10. "errors"
  11. "fmt"
  12. mathRand "math/rand"
  13. "os"
  14. "strings"
  15. "time"
  16. )
  17. const (
  18. RSAAlgorithm = "RSA"
  19. SignatureAlgorithm = "SHA1WithRSA"
  20. letters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
  21. )
  22. // EncryptWithRSA 使用 RSA 公钥加密数据
  23. func EncryptWithRSA(publicKey *rsa.PublicKey, data []byte) ([]byte, error) {
  24. encrypted, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, data)
  25. if err != nil {
  26. return nil, err
  27. }
  28. return encrypted, nil
  29. }
  30. // DecryptWithRSA 使用 RSA 私钥解密数据
  31. func DecryptWithRSA(privateKey *rsa.PrivateKey, encrypted []byte) ([]byte, error) {
  32. hash, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privateKey, encrypted, nil)
  33. if err != nil {
  34. return nil, err
  35. }
  36. return hash, nil
  37. }
  38. // 解析RSA公钥
  39. func ParsePublicKeyFromPEM() (publicKey *rsa.PublicKey, err error) {
  40. pemBlock, err := os.ReadFile("./conf/rsa_public_key.pem")
  41. block, _ := pem.Decode(pemBlock)
  42. if block == nil {
  43. FileLog.Error("公钥解析失败")
  44. return nil, errors.New("公钥解析失败")
  45. }
  46. key, err := x509.ParsePKIXPublicKey(block.Bytes)
  47. if err != nil {
  48. return nil, err
  49. }
  50. publicKey = key.(*rsa.PublicKey)
  51. return
  52. }
  53. // 解析RSA私钥
  54. func ParsePrivateKeyFromPEM() (privateKey *rsa.PrivateKey, err error) {
  55. pemBlock, err := os.ReadFile("./conf/rsa_private_key.pem")
  56. block, _ := pem.Decode(pemBlock)
  57. if block == nil {
  58. FileLog.Error("私钥解析失败")
  59. return nil, errors.New("公钥解析失败")
  60. }
  61. key, err := x509.ParsePKIXPublicKey(block.Bytes)
  62. if err != nil {
  63. return nil, err
  64. }
  65. privateKey = key.(*rsa.PrivateKey)
  66. return
  67. }
  68. type SignatureParam struct {
  69. Nonce string `json:"nonce"`
  70. TimeStamp string `json:"timestamp"`
  71. AppId string `json:"appId"`
  72. }
  73. func (sp *SignatureParam) ToString() string {
  74. return fmt.Sprintf("appid=%s&nonce=%s&timestamp=%s", sp.AppId, sp.Nonce, sp.TimeStamp)
  75. }
  76. type HeaderParam struct {
  77. Signature string `json:"signature"`
  78. Nonce string `json:"nonce"`
  79. TimeStamp string `json:"timestamp"`
  80. AppId string `json:"appId"`
  81. }
  82. func GenerateSignatureAndHeaders() (headerParam HeaderParam, err error) {
  83. if APP_ID == "" {
  84. FileLog.Error("APP_ID为空")
  85. err = errors.New("生成签名头失败,APP_ID未配置")
  86. return
  87. }
  88. if SECRET == "" {
  89. FileLog.Error("SECRET为空")
  90. err = errors.New("生成签名头失败,SECRET未配置")
  91. return
  92. }
  93. signParam := SignatureParam{
  94. AppId: APP_ID,
  95. Nonce: randomString(32),
  96. TimeStamp: fmt.Sprintf("%d", time.Now().Unix()),
  97. }
  98. signature, err := generateHMACSHA256(SECRET, signParam.ToString())
  99. if err != nil {
  100. FileLog.Error("生成签名失败", err)
  101. return
  102. }
  103. headerParam.Nonce = signParam.Nonce
  104. headerParam.TimeStamp = signParam.TimeStamp
  105. headerParam.AppId = signParam.AppId
  106. headerParam.Signature = signature
  107. return
  108. }
  109. func generateHMACSHA256(secret, data string) (encoded string, err error) {
  110. h := hmac.New(sha256.New, []byte(secret))
  111. h.Write([]byte(data))
  112. signature := h.Sum(nil)
  113. // Base64 编码
  114. encoded = base64.StdEncoding.EncodeToString(signature)
  115. // 替换 + 和 / 为 - 和 _
  116. encoded = strings.ReplaceAll(encoded, "+", "-")
  117. encoded = strings.ReplaceAll(encoded, "/", "_")
  118. return
  119. }
  120. func randomString(size int) string {
  121. ret := make([]byte, size)
  122. for i := range ret {
  123. ret[i] = letters[mathRand.Intn(len(letters))]
  124. }
  125. return string(ret)
  126. }