📌Golang📌应用📌加密算法📌7-rsa.go
package crypt
import (
"bytes"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"errors"
"hash"
"strings"
)
var ErrInvalidKeyType = errors.New("invalid key type")
func key2der(key string) ([]byte, error) {
if strings.Contains(key, "-----") {
block, _ := pem.Decode([]byte(key))
if block == nil {
return nil, errors.New("invalid pem text")
}
return block.Bytes, nil
}
return base64.StdEncoding.DecodeString(key)
}
func ParsePkcs1PrivateKey(key string) (*rsa.PrivateKey, error) {
der, err := key2der(key)
if err != nil {
return nil, err
}
return x509.ParsePKCS1PrivateKey(der)
}
func ParsePkcs1PublicKey(key string) (*rsa.PublicKey, error) {
der, err := key2der(key)
if err != nil {
return nil, err
}
return x509.ParsePKCS1PublicKey(der)
}
func ParseRsaPrivateKey(key string) (*rsa.PrivateKey, error) {
der, err := key2der(key)
if err != nil {
return nil, err
}
pri, err := x509.ParsePKCS8PrivateKey(der)
if err != nil {
return nil, err
}
if v, ok := pri.(*rsa.PrivateKey); ok {
return v, nil
}
return nil, ErrInvalidKeyType
}
func ParseRsaPublicKey(key string) (*rsa.PublicKey, error) {
der, err := key2der(key)
if err != nil {
return nil, err
}
pub, err := x509.ParsePKIXPublicKey(der)
if err != nil {
return nil, err
}
if v, ok := pub.(*rsa.PublicKey); ok {
return v, nil
}
return nil, ErrInvalidKeyType
}
func RsaEncryptPKCS1v15(key *rsa.PublicKey, src []byte) (string, error) {
chunk := key.Size() - 11 //长文本需要分段加密
end := len(src)
buf := bytes.NewBuffer(nil)
l := 0
for l < end {
r := l + chunk
if r > end {
r = end
}
b, err := rsa.EncryptPKCS1v15(rand.Reader, key, src[l:r])
if err != nil {
return "", err
}
buf.Write(b)
l = r
}
return base64.StdEncoding.EncodeToString(buf.Bytes()), nil
}
func RsaDecryptPKCS1v15(key *rsa.PrivateKey, s string) ([]byte, error) {
src, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return nil, err
}
chunk := key.Size() //长文本需要分段解密
end := len(src)
buf := bytes.NewBuffer(nil)
l := 0
for l < end {
r := l + chunk
if r > end {
r = end
}
b, err := rsa.DecryptPKCS1v15(rand.Reader, key, src[l:r])
if err != nil {
return nil, err
}
buf.Write(b)
l = r
}
return buf.Bytes(), nil
}
func RsaEncryptOAEP(h hash.Hash, key *rsa.PublicKey, src []byte, label []byte) (string, error) {
chunk := key.Size() - 2*h.Size() - 2 //长文本需要分段加密
if chunk < 1 {
return "", errors.New("hash size is too long for this key size")
}
end := len(src)
buf := bytes.NewBuffer(nil)
l := 0
for l < end {
r := l + chunk
if r > end {
r = end
}
b, err := rsa.EncryptOAEP(h, rand.Reader, key, src[l:r], label)
if err != nil {
return "", err
}
buf.Write(b)
l = r
}
return base64.StdEncoding.EncodeToString(buf.Bytes()), nil
}
func RsaDecryptOAEP(h hash.Hash, key *rsa.PrivateKey, s string, label []byte) ([]byte, error) {
src, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return nil, err
}
chunk := key.Size() //长文本需要分段解密
end := len(src)
buf := bytes.NewBuffer(nil)
l := 0
for l < end {
r := l + chunk
if r > end {
r = end
}
b, err := rsa.DecryptOAEP(h, rand.Reader, key, src[l:r], label)
if err != nil {
return nil, err
}
buf.Write(b)
l = r
}
return buf.Bytes(), nil
}
func RsaSignPKCS1v15(key *rsa.PrivateKey, h crypto.Hash, data []byte) (string, error) {
w := h.New()
w.Write(data)
sign, err := rsa.SignPKCS1v15(rand.Reader, key, h, w.Sum(nil))
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(sign), nil
}
func RsaVerifyPKCS1v15(key *rsa.PublicKey, h crypto.Hash, data []byte, sign string) error {
sig, err := base64.StdEncoding.DecodeString(sign)
if err != nil {
return err
}
w := h.New()
w.Write(data)
return rsa.VerifyPKCS1v15(key, h, w.Sum(nil), sig)
}
func RsaSignPSS(key *rsa.PrivateKey, h crypto.Hash, data []byte) (string, error) {
w := h.New()
w.Write(data)
sign, err := rsa.SignPSS(rand.Reader, key, h, w.Sum(nil), nil)
if err != nil {
return "", err
}
return base64.StdEncoding.EncodeToString(sign), nil
}
func RsaVerifyPSS(key *rsa.PublicKey, h crypto.Hash, data []byte, sign string) error {
sig, err := base64.StdEncoding.DecodeString(sign)
if err != nil {
return err
}
w := h.New()
w.Write(data)
return rsa.VerifyPSS(key, h, w.Sum(nil), sig, nil)
}