// 大数转换、SetString中“1”为大数字符串样式
var n, _ = new(big.Int).SetString("1", 10)
var e = 65537
var d, _ = new(big.Int).SetString("2", 10)
package xrsa
import (
"bytes"
"crypto/rand"
"crypto/rsa"
"encoding/base64"
"errors"
"math/big"
)
type Key struct {
N *big.Int
D *big.Int
E int
}
type XRsa struct {
publicKey *rsa.PublicKey
privateKey *rsa.PrivateKey
}
// NewXRsa 构造非对称加密
func NewXRsa(k Key) (*XRsa, error) {
pub := &rsa.PublicKey{
N: k.N,
E: k.E,
}
pri := &rsa.PrivateKey{
PublicKey: *pub,
D: k.D,
}
return &XRsa{
publicKey: pub,
privateKey: pri,
}, nil
}
// PublicEncrypt 公钥加密
func (r *XRsa) PublicEncrypt(data string) (*bytes.Buffer, error) {
partLen := r.publicKey.N.BitLen()/8 - 11
chunks := split([]byte(data), partLen)
buffer := bytes.NewBufferString("")
for _, chunk := range chunks {
bytesInfo, err := rsa.EncryptPKCS1v15(rand.Reader, r.publicKey, chunk)
if err != nil {
return buffer, err
}
buffer.Write(bytesInfo)
}
return buffer, nil
}
// PrivateDecrypt 私钥解密、支持传入字符串和字节切片类型
// 可使用string()或Bytes()等获取数据信息
func (r *XRsa) PrivateDecrypt(encrypted interface{}) (*bytes.Buffer, error) {
var data string
switch t := encrypted.(type) {
case string:
data = t
case []byte:
data = base64.RawURLEncoding.EncodeToString(t)
default:
return nil, errors.New("type-error")
}
partLen := r.publicKey.N.BitLen() / 8
raw, err := base64.RawURLEncoding.DecodeString(data)
if err != nil {
return nil, errors.New("EnCode-error")
}
chunks := split(raw, partLen)
buffer := bytes.NewBufferString("")
for _, chunk := range chunks {
decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, r.privateKey, chunk)
if err != nil {
return buffer, err
}
buffer.Write(decrypted)
}
return buffer, nil
}
// 将数据按照加密长度进行拆分
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[:])
}
return chunks
}
网友评论