RSA
package rsa
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/subtle"
"crypto/x509"
"encoding/pem"
"errors"
"math/big"
)
const bits = 2048
type RSA struct {
PublicKey []byte `json:"public"`
PrivateKey []byte `json:"private"`
}
func (this *RSA) GenKey(bits int) error {
priKey, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return err
}
pubKey := &priKey.PublicKey
this.PrivateKey = x509.MarshalPKCS1PrivateKey(priKey)
this.PublicKey, err = x509.MarshalPKIXPublicKey(pubKey)
if err != nil {
return err
}
return nil
}
func (this *RSA) Encode(data []byte) ([]byte, error) {
priKey, err := x509.ParsePKCS1PrivateKey(this.PrivateKey)
if err != nil {
return nil, err
}
encryptMsg := []byte{}
maxlength := bits/8 - 11
i := 0
for i < len(data) {
j := i + maxlength
if j > len(data) {
j = len(data)
}
temp, err := rsa.SignPKCS1v15(rand.Reader, priKey, crypto.Hash(0), data[i:j])
if err != nil {
return nil, err
}
encryptMsg = append(encryptMsg, temp...)
i += maxlength
}
return encryptMsg, nil
}
func (this *RSA) EncodePub(data []byte) ([]byte, error) {
pubKey, err := x509.ParsePKIXPublicKey(this.PublicKey)
if err != nil {
return nil, err
}
pub := pubKey.(*rsa.PublicKey)
encryption := []byte{}
maxlength := bits/8 - 11
i := 0
for i < len(data) {
j := i + maxlength
if j > len(data) {
j = len(data)
}
temp, err := rsa.EncryptPKCS1v15(rand.Reader, pub, data[i:j])
if err != nil {
return nil, err
}
encryption = append(encryption, temp...)
i += maxlength
}
return encryption, nil
}
func (this *RSA) Pem() {
if this.PrivateKey != nil {
block := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: this.PrivateKey,
}
this.PrivateKey = pem.EncodeToMemory(block)
}
if this.PublicKey != nil {
block := &pem.Block{
Type: "PUBLIC KEY",
Bytes: this.PrivateKey,
}
this.PublicKey = pem.EncodeToMemory(block)
}
}
func (this *RSA) DePemPub(deta []byte) ([]byte, error) {
blockPub, _ := pem.Decode(this.PublicKey)
if blockPub == nil {
return nil, errors.New("blockPub空")
}
this.PublicKey = blockPub.Bytes
return this.DecodePub(deta)
}
func (this *RSA) DePemPri(deta []byte) ([]byte, error) {
blockPri, _ := pem.Decode(this.PrivateKey)
if blockPri == nil {
return nil, errors.New("blockPub空")
}
this.PrivateKey = blockPri.Bytes
return this.Decode(deta)
}
func (this *RSA) DecodePub(deta []byte) ([]byte, error) {
pubKey, err := x509.ParsePKIXPublicKey(this.PublicKey)
if err != nil {
return nil, err
}
decryptMsg := decrypt(pubKey.(*rsa.PublicKey), deta)
return decryptMsg, nil
}
func (this *RSA) Decode(deta []byte) ([]byte, error) {
prkI, err := x509.ParsePKCS1PrivateKey(this.PrivateKey)
if err != nil {
return nil, err
}
decode := []byte{}
i := 0
for i < len(deta) {
j := i + bits/8
if j > len(deta) {
j = len(deta)
}
temp, err := rsa.DecryptPKCS1v15(rand.Reader, prkI, deta[i:j])
if err != nil {
return nil, err
}
decode = append(decode, temp...)
i += bits / 8
}
return decode, nil
}
func decrypt(pub *rsa.PublicKey, sig []byte) []byte {
k := (pub.N.BitLen() + 7) / 8
m := new(big.Int)
c := new(big.Int).SetBytes(sig)
e := big.NewInt(int64(pub.E))
m.Exp(c, e, pub.N)
em := leftPad(m.Bytes(), k)
firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 1)
lookingForIndex := 1
index := 0
for i := 2; i < len(em); i++ {
equals0 := subtle.ConstantTimeByteEq(em[i], 0)
index = subtle.ConstantTimeSelect(lookingForIndex&equals0, i, index)
lookingForIndex = subtle.ConstantTimeSelect(equals0, 0, lookingForIndex)
}
validPS := subtle.ConstantTimeLessOrEq(2+8, index)
valid := firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) & validPS
index = subtle.ConstantTimeSelect(valid, index+1, 0)
return em[index:]
}
func leftPad(input []byte, size int) (out []byte) {
n := len(input)
if n > size {
n = size
}
out = make([]byte, size)
copy(out[len(out)-n:], input)
return
}