123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- package crypto4go
- import (
- "bytes"
- "crypto"
- "crypto/rand"
- "crypto/rsa"
- "crypto/x509"
- "encoding/pem"
- "errors"
- "strings"
- )
- const (
- kPublicKeyPrefix = "-----BEGIN PUBLIC KEY-----"
- kPublicKeySuffix = "-----END PUBLIC KEY-----"
- kPKCS1Prefix = "-----BEGIN RSA PRIVATE KEY-----"
- KPKCS1Suffix = "-----END RSA PRIVATE KEY-----"
- kPKCS8Prefix = "-----BEGIN PRIVATE KEY-----"
- KPKCS8Suffix = "-----END PRIVATE KEY-----"
- kPublicKeyType = "PUBLIC KEY"
- kPrivateKeyType = "PRIVATE KEY"
- kRSAPrivateKeyType = "RSA PRIVATE KEY"
- )
- var (
- ErrPrivateKeyFailedToLoad = errors.New("crypto4go: private key failed to load")
- ErrPublicKeyFailedToLoad = errors.New("crypto4go: public key failed to load")
- )
- func FormatPublicKey(raw string) []byte {
- return formatKey(raw, kPublicKeyPrefix, kPublicKeySuffix, 64)
- }
- func FormatPKCS1PrivateKey(raw string) []byte {
- raw = strings.Replace(raw, kPKCS8Prefix, "", 1)
- raw = strings.Replace(raw, KPKCS8Suffix, "", 1)
- return formatKey(raw, kPKCS1Prefix, KPKCS1Suffix, 64)
- }
- func FormatPKCS8PrivateKey(raw string) []byte {
- raw = strings.Replace(raw, kPKCS1Prefix, "", 1)
- raw = strings.Replace(raw, KPKCS1Suffix, "", 1)
- return formatKey(raw, kPKCS8Prefix, KPKCS8Suffix, 64)
- }
- func ParsePKCS1PrivateKey(data []byte) (key *rsa.PrivateKey, err error) {
- var block *pem.Block
- block, _ = pem.Decode(data)
- if block == nil {
- return nil, ErrPrivateKeyFailedToLoad
- }
- key, err = x509.ParsePKCS1PrivateKey(block.Bytes)
- if err != nil {
- return nil, err
- }
- return key, err
- }
- func ParsePKCS8PrivateKey(data []byte) (key *rsa.PrivateKey, err error) {
- var block *pem.Block
- block, _ = pem.Decode(data)
- if block == nil {
- return nil, ErrPrivateKeyFailedToLoad
- }
- rawKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
- if err != nil {
- return nil, err
- }
- key, ok := rawKey.(*rsa.PrivateKey)
- if ok == false {
- return nil, ErrPrivateKeyFailedToLoad
- }
- return key, err
- }
- func ParsePublicKey(data []byte) (key *rsa.PublicKey, err error) {
- var block *pem.Block
- block, _ = pem.Decode(data)
- if block == nil {
- return nil, ErrPublicKeyFailedToLoad
- }
- var pubInterface interface{}
- pubInterface, err = x509.ParsePKIXPublicKey(block.Bytes)
- if err != nil {
- return nil, err
- }
- key, ok := pubInterface.(*rsa.PublicKey)
- if !ok {
- return nil, ErrPublicKeyFailedToLoad
- }
- return key, err
- }
- func packageData(data []byte, packageSize int) (r [][]byte) {
- var src = make([]byte, len(data))
- copy(src, data)
- r = make([][]byte, 0)
- if len(src) <= packageSize {
- return append(r, src)
- }
- for len(src) > 0 {
- var p = src[:packageSize]
- r = append(r, p)
- src = src[packageSize:]
- if len(src) <= packageSize {
- r = append(r, src)
- break
- }
- }
- return r
- }
- // RSAEncrypt 使用公钥 key 对数据 data 进行 RSA 加密
- func RSAEncrypt(plaintext, key []byte) ([]byte, error) {
- pubKey, err := ParsePublicKey(key)
- if err != nil {
- return nil, err
- }
- return RSAEncryptWithKey(plaintext, pubKey)
- }
- // RSAEncryptWithKey 使用公钥 key 对数据 data 进行 RSA 加密
- func RSAEncryptWithKey(plaintext []byte, key *rsa.PublicKey) ([]byte, error) {
- var pData = packageData(plaintext, key.N.BitLen()/8-11)
- var ciphertext = make([]byte, 0, 0)
- for _, d := range pData {
- var c, e = rsa.EncryptPKCS1v15(rand.Reader, key, d)
- if e != nil {
- return nil, e
- }
- ciphertext = append(ciphertext, c...)
- }
- return ciphertext, nil
- }
- // RSADecryptWithPKCS1 使用私钥 key 对数据 data 进行 RSA 解密,key 的格式为 pkcs1
- func RSADecryptWithPKCS1(ciphertext, key []byte) ([]byte, error) {
- priKey, err := ParsePKCS1PrivateKey(key)
- if err != nil {
- return nil, err
- }
- return RSADecryptWithKey(ciphertext, priKey)
- }
- // RSADecryptWithPKCS8 使用私钥 key 对数据 data 进行 RSA 解密,key 的格式为 pkcs8
- func RSADecryptWithPKCS8(ciphertext, key []byte) ([]byte, error) {
- priKey, err := ParsePKCS8PrivateKey(key)
- if err != nil {
- return nil, err
- }
- return RSADecryptWithKey(ciphertext, priKey)
- }
- // RSADecryptWithKey 使用私钥 key 对数据 data 进行 RSA 解密
- func RSADecryptWithKey(ciphertext []byte, key *rsa.PrivateKey) ([]byte, error) {
- var pData = packageData(ciphertext, key.PublicKey.N.BitLen()/8)
- var plaintext = make([]byte, 0, 0)
- for _, d := range pData {
- var p, e = rsa.DecryptPKCS1v15(rand.Reader, key, d)
- if e != nil {
- return nil, e
- }
- plaintext = append(plaintext, p...)
- }
- return plaintext, nil
- }
- func RSASignWithPKCS1(plaintext, key []byte, hash crypto.Hash) ([]byte, error) {
- priKey, err := ParsePKCS1PrivateKey(key)
- if err != nil {
- return nil, err
- }
- return RSASignWithKey(plaintext, priKey, hash)
- }
- func RSASignWithPKCS8(plaintext, key []byte, hash crypto.Hash) ([]byte, error) {
- priKey, err := ParsePKCS8PrivateKey(key)
- if err != nil {
- return nil, err
- }
- return RSASignWithKey(plaintext, priKey, hash)
- }
- func RSASignWithKey(plaintext []byte, key *rsa.PrivateKey, hash crypto.Hash) ([]byte, error) {
- var h = hash.New()
- h.Write(plaintext)
- var hashed = h.Sum(nil)
- return rsa.SignPKCS1v15(rand.Reader, key, hash, hashed)
- }
- func RSAVerify(ciphertext, sign, key []byte, hash crypto.Hash) error {
- pubKey, err := ParsePublicKey(key)
- if err != nil {
- return err
- }
- return RSAVerifyWithKey(ciphertext, sign, pubKey, hash)
- }
- func RSAVerifyWithKey(ciphertext, sign []byte, key *rsa.PublicKey, hash crypto.Hash) error {
- var h = hash.New()
- h.Write(ciphertext)
- var hashed = h.Sum(nil)
- return rsa.VerifyPKCS1v15(key, hash, hashed, sign)
- }
- func getPublicKeyBytes(publicKey *rsa.PublicKey) ([]byte, error) {
- pubDer, err := x509.MarshalPKIXPublicKey(publicKey)
- if err != nil {
- return nil, err
- }
- pubBlock := &pem.Block{Type: kPublicKeyType, Bytes: pubDer}
- var pubBuf bytes.Buffer
- if err = pem.Encode(&pubBuf, pubBlock); err != nil {
- return nil, err
- }
- return pubBuf.Bytes(), nil
- }
- func GenRSAKeyWithPKCS1(bits int) (privateKey, publicKey []byte, err error) {
- priKey, err := rsa.GenerateKey(rand.Reader, bits)
- if err != nil {
- return nil, nil, err
- }
- priDer := x509.MarshalPKCS1PrivateKey(priKey)
- priBlock := &pem.Block{Type: kRSAPrivateKeyType, Bytes: priDer}
- var priBuf bytes.Buffer
- if err = pem.Encode(&priBuf, priBlock); err != nil {
- return nil, nil, err
- }
- publicKey, err = getPublicKeyBytes(&priKey.PublicKey)
- if err != nil {
- return nil, nil, err
- }
- privateKey = priBuf.Bytes()
- return privateKey, publicKey, err
- }
- func GenRSAKeyWithPKCS8(bits int) (privateKey, publicKey []byte, err error) {
- priKey, err := rsa.GenerateKey(rand.Reader, bits)
- if err != nil {
- return nil, nil, err
- }
- priDer, err := x509.MarshalPKCS8PrivateKey(priKey)
- if err != nil {
- return nil, nil, err
- }
- priBlock := &pem.Block{Type: kPrivateKeyType, Bytes: priDer}
- var priBuf bytes.Buffer
- if err = pem.Encode(&priBuf, priBlock); err != nil {
- return nil, nil, err
- }
- publicKey, err = getPublicKeyBytes(&priKey.PublicKey)
- if err != nil {
- return nil, nil, err
- }
- privateKey = priBuf.Bytes()
- return privateKey, publicKey, err
- }
|