golang rsa 加解密兼容 PKCS8 PKCS1

package rsa

import (
	"bytes"
	"crypto/rand"
	r "crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"encoding/pem"
	"errors"
	"strings"
)

// RSAEncryptor 结构体
type RSACryptor struct {
	privateKey []byte
	publicKey  []byte
	rsaPrivateKey *r.PrivateKey
    rsaPublicKey  *r.PublicKey
}

// new struct
func NewRSACryptor(privateKey, publicKey string) (obj *RSACryptor, err error) {
	obj = &RSACryptor{
		privateKey: []byte(privateKey),
		publicKey: []byte(publicKey),
	}
	obj.rsaPrivateKey, err = obj.getRsaPrivateKey()
	if err != nil {
		return 
	}
	obj.rsaPublicKey, err = obj.getRsaPublicKey()
	if err != nil {
		return 
	}
	return 
}
 
// 加密
func (this *RSACryptor) Encrypt(origData []byte) ([]byte, error) {
	//加密
	return r.EncryptPKCS1v15(rand.Reader, this.rsaPublicKey, origData)
}
 
// 解密
func  (this *RSACryptor) Decrypt(ciphertext string) (string, error) {
	partLen := this.rsaPublicKey.N.BitLen() / 8
	ciphertext = strings.Replace(ciphertext, " ", "", -1)
	raw, err := base64.RawURLEncoding.DecodeString(ciphertext)
	if err != nil {
		return "", errors.New(ciphertext)
	}
    chunks :=  split([]byte(raw), partLen)
    buffer := bytes.NewBufferString("")
    for _, chunk := range chunks {
        decrypted, err := r.DecryptPKCS1v15(rand.Reader, this.rsaPrivateKey, chunk)
        if err != nil {
            return "", err
        }
        buffer.Write(decrypted)
    }
    return buffer.String(), err
}

func split(buf []byte, lim int) [][]byte {
    var chunk []byte
    chunks := make([][]byte, 0, len(buf)/lim+1)
    for len(buf) >= lim {
        chunk, buf = buf[:lim], buf[lim:]
        chunks = append(chunks, chunk)
    }
    if len(buf) > 0 {
        chunks = append(chunks, buf[:len(buf)])
    }
    return chunks
}

func  (this *RSACryptor) getRsaPublicKey() (*r.PublicKey, error) {
	//解密pem格式的公钥
	block, _ := pem.Decode(this.publicKey)
	if block == nil {
		return nil, errors.New("public key error")
	}
	// 解析公钥
	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return nil, err
	}
	// 类型断言
	return pubInterface.(*r.PublicKey),nil
}

func  (this *RSACryptor) getRsaPrivateKey() (*r.PrivateKey, error) {	
	//解密
	block, _ := pem.Decode(this.privateKey)
	if block == nil {
		return nil, errors.New("private key error!")
	}
	//解析PKCS1格式的私钥
	privInterface, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
		if err != nil {
			return nil, err
		}
		return priv, err
	} else {
		// 类型断言
		return privInterface.(*r.PrivateKey), nil
	}
	
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值