Go RSA 加密解密和签名验证库
package crypto
import ( "crypto" "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/base64" "encoding/pem" "errors" "github.com/containous/traefik/v2/pkg/log" )
// pkcsClient 结构体定义了 RSA 密钥和加密/解密/签名/验证方法 type pkcsClient struct { privateKey *rsa.PrivateKey publicKey *rsa.PublicKey }
// Type 枚举类型表示私钥类型 type Type int64
const ( PKCS1 Type = iota PKCS8 )
// Encrypt 方法使用公钥加密明文 func (this *pkcsClient) Encrypt(plaintext []byte) ([]byte, error) { return rsa.EncryptPKCS1v15(rand.Reader, this.publicKey, plaintext) }
// Decrypt 方法使用私钥解密密文 func (this *pkcsClient) Decrypt(ciphertext []byte) ([]byte, error) { return rsa.DecryptPKCS1v15(rand.Reader, this.privateKey, ciphertext) }
// Sign 方法使用私钥对数据进行签名 func (this *pkcsClient) Sign(src []byte, hash crypto.Hash) ([]byte, error) { h := hash.New() h.Write(src) hashed := h.Sum(nil) return rsa.SignPKCS1v15(rand.Reader, this.privateKey, hash, hashed) }
// Verify 方法使用公钥验证签名 func (this *pkcsClient) Verify(src []byte, sign []byte, hash crypto.Hash) error { h := hash.New() h.Write(src) hashed := h.Sum(nil) return rsa.VerifyPKCS1v15(this.publicKey, hash, hashed, sign) }
// Cipher 接口定义了加密/解密/签名/验证方法 type Cipher interface { Encrypt(plaintext []byte) ([]byte, error) Decrypt(ciphertext []byte) ([]byte, error) Sign(src []byte, hash crypto.Hash) ([]byte, error) Verify(src []byte, sign []byte, hash crypto.Hash) error }
// NewDefault 函数创建默认的 Cipher 实例,使用 PKCS8 私钥格式和 PEM 编码 func NewDefault(privateKey, publicKey string) (Cipher, error) { blockPri, _ := pem.Decode([]byte(privateKey)) if blockPri == nil { return nil, errors.New("private key error") }
blockPub, _ := pem.Decode([]byte(publicKey))
if blockPub == nil {
return nil, errors.New("public key error")
}
return NewRsa(blockPri.Bytes, blockPub.Bytes, PKCS8)
}
// NewRsa 函数创建 RSA Cipher 实例,支持 PKCS1 和 PKCS8 私钥格式 func NewRsa(privateKey, publicKey []byte, privateKeyType Type) (Cipher, error) { priKey, err := genPriKey(privateKey, privateKeyType) if err != nil { return nil, err } pubKey, err := genPubKey(publicKey) if err != nil { return nil, err } return &pkcsClient{privateKey: priKey, publicKey: pubKey}, nil }
// genPubKey 函数解析公钥 func genPubKey(publicKey []byte) (*rsa.PublicKey, error) { pub, err := x509.ParsePKIXPublicKey(publicKey) if err != nil { return nil, err } return pub.(*rsa.PublicKey), nil }
// genPriKey 函数解析私钥 func genPriKey(privateKey []byte, privateKeyType Type) (*rsa.PrivateKey, error) { var priKey *rsa.PrivateKey var err error switch privateKeyType { case PKCS1: { priKey, err = x509.ParsePKCS1PrivateKey([]byte(privateKey)) if err != nil { return nil, err } } case PKCS8: { prkI, err := x509.ParsePKCS8PrivateKey([]byte(privateKey)) if err != nil { return nil, err } priKey = prkI.(*rsa.PrivateKey) } default: { return nil, errors.New("unsupport private key type") } } return priKey, nil }
// KeyPair 函数生成 RSA 密钥对,并返回 Base64 编码的字符串 func KeyPair() (priKey, pubKey string, err error) { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { log.WithoutContext().Errorln(err) return } priKey = base64.StdEncoding.EncodeToString(x509.MarshalPKCS1PrivateKey(privateKey))
// 生成公钥文件
publicKey := &privateKey.PublicKey
derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
log.WithoutContext().Errorln(err)
return
}
pubKey = base64.StdEncoding.EncodeToString(derPkix)
return
}
// KeyPairPem 函数生成 RSA 密钥对,并返回 PEM 编码的字符串 func KeyPairPem() (priKey, pubKey string, err error) { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return "", "", err } var pemPrivateBlock = &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey), } priKey = string(pem.EncodeToMemory(pemPrivateBlock))
// 生成公钥文件
publicKey := &privateKey.PublicKey
derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
return "", "", err
}
block := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: derPkix,
}
pubKey = string(pem.EncodeToMemory(block))
return priKey, pubKey, nil
}
// ... (其他函数和代码省略) ...
原文地址: https://www.cveoy.top/t/topic/pg98 著作权归作者所有。请勿转载和采集!