广告平台(站长使用)
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

rsa.go 3.8 KiB

1ヶ月前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. package utils
  2. import (
  3. "bytes"
  4. "crypto/rand"
  5. "crypto/rsa"
  6. "crypto/x509"
  7. "encoding/pem"
  8. "errors"
  9. "fmt"
  10. "io/ioutil"
  11. "log"
  12. "os"
  13. )
  14. // 生成私钥文件 TODO 未指定路径
  15. func RsaKeyGen(bits int) error {
  16. privateKey, err := rsa.GenerateKey(rand.Reader, bits)
  17. if err != nil {
  18. return err
  19. }
  20. derStream := x509.MarshalPKCS1PrivateKey(privateKey)
  21. block := &pem.Block{
  22. Type: "RSA PRIVATE KEY",
  23. Bytes: derStream,
  24. }
  25. priFile, err := os.Create("private.pem")
  26. if err != nil {
  27. return err
  28. }
  29. err = pem.Encode(priFile, block)
  30. priFile.Close()
  31. if err != nil {
  32. return err
  33. }
  34. // 生成公钥文件
  35. publicKey := &privateKey.PublicKey
  36. derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
  37. if err != nil {
  38. return err
  39. }
  40. block = &pem.Block{
  41. Type: "PUBLIC KEY",
  42. Bytes: derPkix,
  43. }
  44. pubFile, err := os.Create("public.pem")
  45. if err != nil {
  46. return err
  47. }
  48. err = pem.Encode(pubFile, block)
  49. pubFile.Close()
  50. if err != nil {
  51. return err
  52. }
  53. return nil
  54. }
  55. // 生成私钥文件, 返回 privateKey , publicKey, error
  56. func RsaKeyGenText(bits int) (string, string, error) { // bits 字节位 1024/2048
  57. privateKey, err := rsa.GenerateKey(rand.Reader, bits)
  58. if err != nil {
  59. return "", "", err
  60. }
  61. derStream := x509.MarshalPKCS1PrivateKey(privateKey)
  62. block := &pem.Block{
  63. Type: "RSA PRIVATE KEY",
  64. Bytes: derStream,
  65. }
  66. priBuff := bytes.NewBuffer(nil)
  67. err = pem.Encode(priBuff, block)
  68. if err != nil {
  69. return "", "", err
  70. }
  71. // 生成公钥文件
  72. publicKey := &privateKey.PublicKey
  73. derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
  74. if err != nil {
  75. return "", "", err
  76. }
  77. block = &pem.Block{
  78. Type: "PUBLIC KEY",
  79. Bytes: derPkix,
  80. }
  81. pubBuff := bytes.NewBuffer(nil)
  82. err = pem.Encode(pubBuff, block)
  83. if err != nil {
  84. return "", "", err
  85. }
  86. return priBuff.String(), pubBuff.String(), nil
  87. }
  88. // 加密
  89. func RsaEncrypt(rawData, publicKey []byte) ([]byte, error) {
  90. block, _ := pem.Decode(publicKey)
  91. if block == nil {
  92. return nil, errors.New("public key error")
  93. }
  94. pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
  95. if err != nil {
  96. return nil, err
  97. }
  98. pub := pubInterface.(*rsa.PublicKey)
  99. return rsa.EncryptPKCS1v15(rand.Reader, pub, rawData)
  100. }
  101. // 公钥加密
  102. func RsaEncrypts(data, keyBytes []byte) []byte {
  103. //解密pem格式的公钥
  104. block, _ := pem.Decode(keyBytes)
  105. if block == nil {
  106. panic(errors.New("public key error"))
  107. }
  108. // 解析公钥
  109. pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
  110. if err != nil {
  111. panic(err)
  112. }
  113. // 类型断言
  114. pub := pubInterface.(*rsa.PublicKey)
  115. //加密
  116. ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, pub, data)
  117. if err != nil {
  118. panic(err)
  119. }
  120. return ciphertext
  121. }
  122. // 解密
  123. func RsaDecrypt(cipherText, privateKey []byte) ([]byte, error) {
  124. block, _ := pem.Decode(privateKey)
  125. if block == nil {
  126. return nil, errors.New("private key error")
  127. }
  128. priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
  129. if err != nil {
  130. return nil, err
  131. }
  132. return rsa.DecryptPKCS1v15(rand.Reader, priv, cipherText)
  133. }
  134. // 从证书获取公钥
  135. func OpensslPemGetPublic(pathOrString string) (interface{}, error) {
  136. var certPem []byte
  137. var err error
  138. if IsFile(pathOrString) && Exists(pathOrString) {
  139. certPem, err = ioutil.ReadFile(pathOrString)
  140. if err != nil {
  141. return nil, err
  142. }
  143. if string(certPem) == "" {
  144. return nil, errors.New("empty pem file")
  145. }
  146. } else {
  147. if pathOrString == "" {
  148. return nil, errors.New("empty pem string")
  149. }
  150. certPem = StringToSlice(pathOrString)
  151. }
  152. block, rest := pem.Decode(certPem)
  153. if block == nil || block.Type != "PUBLIC KEY" {
  154. //log.Fatal("failed to decode PEM block containing public key")
  155. return nil, errors.New("failed to decode PEM block containing public key")
  156. }
  157. pub, err := x509.ParsePKIXPublicKey(block.Bytes)
  158. if err != nil {
  159. log.Fatal(err)
  160. }
  161. fmt.Printf("Got a %T, with remaining data: %q", pub, rest)
  162. return pub, nil
  163. }