RSA加密解密(无数据大小限制go实现)

RSA加解密中必须考虑到的密钥长度、明文长度和密文长度问题。明文长度需要小于密钥长度,而密文长度则等于密钥长度。因此当加密内容长度大于密钥长度时,有效的RSA加解密就需要对内容进行分段。

这是因为,RSA算法本身要求加密内容也就是明文长度m必须0<m<密钥长度n。如果小于这个长度就需要进行padding,因为如果没有padding,用户无法确分解密后内容的真实长度,字符串之类的内容问题还不大,以0作为结束符,但对二进制数据就很难理解,因为不确定后面的0是内容还是内容结束符。而只要用到padding,那么就要占用实际的明文长度,于是实际明文长度需要减去padding字节长度。我们一般使用的padding标准有NoPPadding、OAEPPadding、PKCS1Padding等,其中PKCS#1建议的padding就占用了11个字节。

这样,对于1024长度的密钥。128字节(1024bits)-减去11字节正好是117字节,但对于RSA加密来讲,padding也是参与加密的,所以,依然按照1024bits去理解,但实际的明文只有117字节了。

Go实现

  1. package xrsa


  2. import (

  3.     "encoding/pem"

  4.     "encoding/base64"

  5.     "crypto/x509"

  6.     "crypto/rsa"

  7.     "crypto/rand"

  8.     "errors"

  9.     "crypto"

  10.     "io"

  11.     "bytes"

  12.     "encoding/asn1"

  13. )


  14. const (

  15.     CHAR_SET = "UTF-8"

  16.     BASE_64_FORMAT = "UrlSafeNoPadding"

  17.     RSA_ALGORITHM_KEY_TYPE = "PKCS8"

  18.     RSA_ALGORITHM_SIGN = crypto.SHA256

  19. )


  20. type XRsa struct {

  21.     publicKey *rsa.PublicKey

  22.     privateKey *rsa.PrivateKey

  23. }


  24. // 生成密钥对

  25. func CreateKeys(publicKeyWriter, privateKeyWriter io.Writer, keyLength int) error {

  26.     // 生成私钥文件

  27.     privateKey, err := rsa.GenerateKey(rand.Reader, keyLength)

  28.     if err != nil {

  29.         return err

  30.     }

  31.     derStream := MarshalPKCS8PrivateKey(privateKey)

  32.     block := &pem.Block{

  33.         Type:  "PRIVATE KEY",

  34.         Bytes: derStream,

  35.     }

  36.     err = pem.Encode(privateKeyWriter, block)

  37.     if err != nil {

  38.         return err

  39.     }


  40.     // 生成公钥文件

  41.     publicKey := &privateKey.PublicKey

  42.     derPkix, err := x509.MarshalPKIXPublicKey(publicKey)

  43.     if err != nil {

  44.         return err

  45.     }

  46.     block = &pem.Block{

  47.         Type:  "PUBLIC KEY",

  48.         Bytes: derPkix,

  49.     }

  50.     err = pem.Encode(publicKeyWriter, block)

  51.     if err != nil {

  52.         return err

  53.     }


  54.     return nil

  55. }


  56. func NewXRsa(publicKey []byte, privateKey []byte) (*XRsa, error) {

  57.     block, _ := pem.Decode(publicKey)

  58.     if block == nil {

  59.         return nil, errors.New("public key error")

  60.     }

  61.     pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)

  62.     if err != nil {

  63.         return nil, err

  64.     }

  65.     pub := pubInterface.(*rsa.PublicKey)


  66.     block, _ = pem.Decode(privateKey)

  67.     if block == nil {

  68.         return nil, errors.New("private key error!")

  69.     }

  70.     priv, err := x509.ParsePKCS8PrivateKey(block.Bytes)

  71.     if err != nil {

  72.         return nil, err

  73.     }


  74.     pri, ok := priv.(*rsa.PrivateKey)

  75.     if ok {

  76.         return &XRsa {

  77.             publicKey: pub,

  78.             privateKey: pri,

  79.         }, nil

  80.     } else {

  81.         return nil, errors.New("private key not supported")

  82.     }

  83. }


  84. // 公钥加密

  85. func (r *XRsa) PublicEncrypt(data string) (string, error) {

  86.     partLen := r.publicKey.N.BitLen() / 8 - 11

  87.     chunks := split([]byte(data), partLen)


  88.     buffer := bytes.NewBufferString("")

  89.     for _, chunk := range chunks {

  90.         bytes, err := rsa.EncryptPKCS1v15(rand.Reader, r.publicKey, chunk)

  91.         if err != nil {

  92.             return "", err

  93.         }

  94.         buffer.Write(bytes)

  95.     }


  96.     return base64.RawURLEncoding.EncodeToString(buffer.Bytes()), nil

  97. }


  98. // 私钥解密

  99. func (r *XRsa) PrivateDecrypt(encrypted string) (string, error) {

  100.     partLen := r.publicKey.N.BitLen() / 8

  101.     raw, err := base64.RawURLEncoding.DecodeString(encrypted)

  102.     chunks := split([]byte(raw), partLen)


  103.     buffer := bytes.NewBufferString("")

  104.     for _, chunk := range chunks {

  105.         decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, r.privateKey, chunk)

  106.         if err != nil {

  107.             return "", err

  108.         }

  109.         buffer.Write(decrypted)

  110.     }


  111.     return buffer.String(), err

  112. }


  113. // 数据加签

  114. func (r *XRsa) Sign(data string) (string, error) {

  115.     h := RSA_ALGORITHM_SIGN.New()

  116.     h.Write([]byte(data))

  117.     hashed := h.Sum(nil)


  118.     sign, err := rsa.SignPKCS1v15(rand.Reader, r.privateKey, RSA_ALGORITHM_SIGN, hashed)

  119.     if err != nil {

  120.         return "", err

  121.     }

  122.     return base64.RawURLEncoding.EncodeToString(sign), err

  123. }


  124. // 数据验签

  125. func (r *XRsa) Verify(data string, sign string) error {

  126.     h := RSA_ALGORITHM_SIGN.New()

  127.     h.Write([]byte(data))

  128.     hashed := h.Sum(nil)


  129.     decodedSign, err := base64.RawURLEncoding.DecodeString(sign)

  130.     if err != nil {

  131.         return err

  132.     }


  133.     return rsa.VerifyPKCS1v15(r.publicKey, RSA_ALGORITHM_SIGN, hashed, decodedSign)

  134. }


  135. func MarshalPKCS8PrivateKey(key *rsa.PrivateKey) []byte {

  136.     info := struct {

  137.         Version             int

  138.         PrivateKeyAlgorithm []asn1.ObjectIdentifier

  139.         PrivateKey          []byte

  140.     }{}

  141.     info.Version = 0

  142.     info.PrivateKeyAlgorithm = make([]asn1.ObjectIdentifier, 1)

  143.     info.PrivateKeyAlgorithm[0] = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}

  144.     info.PrivateKey = x509.MarshalPKCS1PrivateKey(key)


  145.     k, _ := asn1.Marshal(info)

  146.     return k

  147. }


  148. func split(buf []byte, lim int) [][]byte {

  149.     var chunk []byte

  150.     chunks := make([][]byte, 0, len(buf)/lim+1)

  151.     for len(buf) >= lim {

  152.         chunk, buf = buf[:lim], buf[lim:]

  153.         chunks = append(chunks, chunk)

  154.     }

  155.     if len(buf) > 0 {

  156.         chunks = append(chunks, buf[:len(buf)])

  157.     }

  158.     return chunks

  159. }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值