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
}
}