怎么用 GO 实现 RSA 的公钥加密私钥解密呢

发布于 2022-08-31 20:33:23 字数 19 浏览 10 评论 0

不是私钥加密公钥解密

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

九命猫 2022-09-07 20:33:23
import (
    "crypto/rand"
    "crypto/rsa"
    "crypto/x509"
    "encoding/pem"
    "errors"
)

// 加密
func RsaEncrypt(publicKey []byte, origData []byte) ([]byte, error) {
    block, _ := pem.Decode(publicKey)
    if block == nil {
        return nil, errors.New("public key error")
    }
    pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
    if err != nil {
        return nil, err
    }
    pub := pubInterface.(*rsa.PublicKey)
    return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
}

// 解密
func RsaDecrypt(privateKey []byte, ciphertext []byte) ([]byte, error) {
    block, _ := pem.Decode(privateKey)
    if block == nil {
        return nil, errors.New("private key error!")
    }
    priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
    if err != nil {
        return nil, err
    }
    return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
}
蛮可爱 2022-09-07 20:33:23

公钥解密,私钥加密,原生go的实现: https://gist.github.com/yanue...

// pure-go  implementation missing in 'crypto/rsa' package of openssl functions RSA_public_encrypt and RSA_private_decrypt.
// see: https://github.com/buf1024/golib/blob/master/crypt/rsa.go

package rsa

import (
    "crypto"
    "crypto/rsa"
    "errors"
    "fmt"
    "math/big"
)

// copy from crypto/rsa/pkcs1v5.go
var hashPrefixes = map[crypto.Hash][]byte{
    crypto.MD5:       {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10},
    crypto.SHA1:      {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14},
    crypto.SHA224:    {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c},
    crypto.SHA256:    {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20},
    crypto.SHA384:    {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30},
    crypto.SHA512:    {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40},
    crypto.MD5SHA1:   {}, // A special TLS case which doesn't use an ASN1 prefix.
    crypto.RIPEMD160: {0x30, 0x20, 0x30, 0x08, 0x06, 0x06, 0x28, 0xcf, 0x06, 0x03, 0x00, 0x31, 0x04, 0x14},
}

// copy from crypto/rsa/pkcs1v5.go
func encrypt(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int {
    e := big.NewInt(int64(pub.E))
    c.Exp(m, e, pub.N)
    return c
}

// copy from crypto/rsa/pkcs1v5.go
func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte, err error) {
    // Special case: crypto.Hash(0) is used to indicate that the data is
    // signed directly.
    if hash == 0 {
        return inLen, nil, nil
    }

    hashLen = hash.Size()
    if inLen != hashLen {
        return 0, nil, errors.New("crypto/rsa: input must be hashed message")
    }
    prefix, ok := hashPrefixes[hash]
    if !ok {
        return 0, nil, errors.New("crypto/rsa: unsupported hash function")
    }
    return
}

// copy from crypto/rsa/pkcs1v5.go
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
}

// un LeftPad
func unLeftPad(input []byte) (out []byte) {
    n := len(input)
    t := 2
    for i := 2; i < n; i++ {
        if input[i] == 0xff {
            t = t + 1
        } else {
            if input[i] == input[0] {
                t = t + int(input[1])
            }
            break
        }
    }
    out = make([]byte, n-t)
    copy(out, input[t:])
    return
}

// copy&modified from crypto/rsa/pkcs1v5.go
func publicDecrypt(pub *rsa.PublicKey, hash crypto.Hash, hashed []byte, sig []byte) (out []byte, err error) {
    hashLen, prefix, err := pkcs1v15HashInfo(hash, len(hashed))
    if err != nil {
        return nil, err
    }

    tLen := len(prefix) + hashLen
    k := (pub.N.BitLen() + 7) / 8
    if k < tLen+11 {
        return nil, fmt.Errorf("length illegal")
    }

    c := new(big.Int).SetBytes(sig)
    m := encrypt(new(big.Int), pub, c)
    em := leftPad(m.Bytes(), k)
    out = unLeftPad(em)

    err = nil
    return
}

// pure-go realization of RSA_private_encrypt
func rsaPrivateEncrypt(pri *rsa.PrivateKey, data []byte) ([]byte, error) {
    signData, err := rsa.SignPKCS1v15(nil, pri, crypto.Hash(0), data)
    if err != nil {
        return nil, err
    }
    return signData, nil
}

// pure-go realization of RSA_public_decrypt
func rsaPublicDecrypt(pub *rsa.PublicKey, data []byte) ([]byte, error) {
    decData, err := publicDecrypt(pub, crypto.Hash(0), nil, data)
    if err != nil {
        return nil, err
    }
    return decData, nil
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文