附近小店
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

232 行
5.2 KiB

  1. package utils
  2. import (
  3. "bytes"
  4. "crypto"
  5. "crypto/rand"
  6. "crypto/rsa"
  7. "crypto/sha256"
  8. "crypto/x509"
  9. "encoding/base64"
  10. "encoding/pem"
  11. "errors"
  12. "fmt"
  13. "io/ioutil"
  14. "log"
  15. "os"
  16. "strings"
  17. )
  18. // 生成私钥文件 TODO 未指定路径
  19. func RsaKeyGen(bits int) error {
  20. privateKey, err := rsa.GenerateKey(rand.Reader, bits)
  21. if err != nil {
  22. return err
  23. }
  24. derStream := x509.MarshalPKCS1PrivateKey(privateKey)
  25. block := &pem.Block{
  26. Type: "RSA PRIVATE KEY",
  27. Bytes: derStream,
  28. }
  29. priFile, err := os.Create("private.pem")
  30. if err != nil {
  31. return err
  32. }
  33. err = pem.Encode(priFile, block)
  34. priFile.Close()
  35. if err != nil {
  36. return err
  37. }
  38. // 生成公钥文件
  39. publicKey := &privateKey.PublicKey
  40. derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
  41. if err != nil {
  42. return err
  43. }
  44. block = &pem.Block{
  45. Type: "PUBLIC KEY",
  46. Bytes: derPkix,
  47. }
  48. pubFile, err := os.Create("public.pem")
  49. if err != nil {
  50. return err
  51. }
  52. err = pem.Encode(pubFile, block)
  53. pubFile.Close()
  54. if err != nil {
  55. return err
  56. }
  57. return nil
  58. }
  59. // 生成私钥文件, 返回 privateKey , publicKey, error
  60. func RsaKeyGenText(bits int) (string, string, error) { // bits 字节位 1024/2048
  61. privateKey, err := rsa.GenerateKey(rand.Reader, bits)
  62. if err != nil {
  63. return "", "", err
  64. }
  65. derStream := x509.MarshalPKCS1PrivateKey(privateKey)
  66. block := &pem.Block{
  67. Type: "RSA PRIVATE KEY",
  68. Bytes: derStream,
  69. }
  70. priBuff := bytes.NewBuffer(nil)
  71. err = pem.Encode(priBuff, block)
  72. if err != nil {
  73. return "", "", err
  74. }
  75. // 生成公钥文件
  76. publicKey := &privateKey.PublicKey
  77. derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
  78. if err != nil {
  79. return "", "", err
  80. }
  81. block = &pem.Block{
  82. Type: "PUBLIC KEY",
  83. Bytes: derPkix,
  84. }
  85. pubBuff := bytes.NewBuffer(nil)
  86. err = pem.Encode(pubBuff, block)
  87. if err != nil {
  88. return "", "", err
  89. }
  90. return priBuff.String(), pubBuff.String(), nil
  91. }
  92. // 加密
  93. func RsaEncrypt(rawData, publicKey []byte) ([]byte, error) {
  94. block, _ := pem.Decode(publicKey)
  95. if block == nil {
  96. return nil, errors.New("public key error")
  97. }
  98. pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
  99. if err != nil {
  100. return nil, err
  101. }
  102. pub := pubInterface.(*rsa.PublicKey)
  103. return rsa.EncryptPKCS1v15(rand.Reader, pub, rawData)
  104. }
  105. // 公钥加密
  106. func RsaEncrypts(data, keyBytes []byte) []byte {
  107. //解密pem格式的公钥
  108. block, _ := pem.Decode(keyBytes)
  109. if block == nil {
  110. panic(errors.New("public key error"))
  111. }
  112. // 解析公钥
  113. pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
  114. if err != nil {
  115. panic(err)
  116. }
  117. // 类型断言
  118. pub := pubInterface.(*rsa.PublicKey)
  119. //加密
  120. ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, pub, data)
  121. if err != nil {
  122. panic(err)
  123. }
  124. return ciphertext
  125. }
  126. // 解密
  127. func RsaDecrypt(cipherText, privateKey []byte) ([]byte, error) {
  128. block, _ := pem.Decode(privateKey)
  129. if block == nil {
  130. return nil, errors.New("private key error")
  131. }
  132. priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
  133. if err != nil {
  134. return nil, err
  135. }
  136. return rsa.DecryptPKCS1v15(rand.Reader, priv, cipherText)
  137. }
  138. func SyRsaEncrypt(signStr, signature, privateKeyBytes string) error {
  139. h := sha256.New()
  140. h.Write([]byte(signStr))
  141. d := h.Sum(nil)
  142. sign, _ := base64.StdEncoding.DecodeString(signature)
  143. pub, err := ParsePKIXPublicKey(privateKeyBytes)
  144. err = rsa.VerifyPKCS1v15(pub, crypto.SHA256, d, sign)
  145. if err != nil {
  146. return err
  147. }
  148. return nil
  149. }
  150. func FormatPublicKey(publicKey string) (pKey string) {
  151. var buffer strings.Builder
  152. buffer.WriteString("-----BEGIN PUBLIC KEY-----\n")
  153. rawLen := 64
  154. keyLen := len(publicKey)
  155. raws := keyLen / rawLen
  156. temp := keyLen % rawLen
  157. if temp > 0 {
  158. raws++
  159. }
  160. start := 0
  161. end := start + rawLen
  162. for i := 0; i < raws; i++ {
  163. if i == raws-1 {
  164. buffer.WriteString(publicKey[start:])
  165. } else {
  166. buffer.WriteString(publicKey[start:end])
  167. }
  168. buffer.WriteByte('\n')
  169. start += rawLen
  170. end = start + rawLen
  171. }
  172. buffer.WriteString("-----END PUBLIC KEY-----\n")
  173. pKey = buffer.String()
  174. return
  175. }
  176. func ParsePKIXPublicKey(privateKey string) (*rsa.PublicKey, error) {
  177. privateKey = FormatPublicKey(privateKey)
  178. // 2、解码私钥字节,生成加密对象
  179. block, _ := pem.Decode([]byte(privateKey))
  180. if block == nil {
  181. return nil, errors.New("私钥信息错误!")
  182. }
  183. // 3、解析DER编码的私钥,生成私钥对象
  184. priKey, err := x509.ParsePKIXPublicKey(block.Bytes)
  185. if err != nil {
  186. return nil, err
  187. }
  188. return priKey.(*rsa.PublicKey), nil
  189. }
  190. // 从证书获取公钥
  191. func OpensslPemGetPublic(pathOrString string) (interface{}, error) {
  192. var certPem []byte
  193. var err error
  194. if IsFile(pathOrString) && Exists(pathOrString) {
  195. certPem, err = ioutil.ReadFile(pathOrString)
  196. if err != nil {
  197. return nil, err
  198. }
  199. if string(certPem) == "" {
  200. return nil, errors.New("empty pem file")
  201. }
  202. } else {
  203. if pathOrString == "" {
  204. return nil, errors.New("empty pem string")
  205. }
  206. certPem = StringToSlice(pathOrString)
  207. }
  208. block, rest := pem.Decode(certPem)
  209. if block == nil || block.Type != "PUBLIC KEY" {
  210. //log.Fatal("failed to decode PEM block containing public key")
  211. return nil, errors.New("failed to decode PEM block containing public key")
  212. }
  213. pub, err := x509.ParsePKIXPublicKey(block.Bytes)
  214. if err != nil {
  215. log.Fatal(err)
  216. }
  217. fmt.Printf("Got a %T, with remaining data: %q", pub, rest)
  218. return pub, nil
  219. }