go rsa加密和解密 签名和验证

网上关于rsa的用法很多,尤其是 https://cloud.tencent.com/developer/section/1140761,但是上面的例子不全面

package utils

import (
    "bytes"
    "crypto"
    "crypto/rand"
    "crypto/rsa"
    "crypto/sha256"
    "crypto/x509"
    "encoding/hex"
    "encoding/pem"
    "fmt"
    "os"
)

func RSAEncryptOAEP(publicKeypem, labeltext, plaintext string) (ciphertext string) {
    publicBlock, _ := pem.Decode([]byte(publicKeypem))
    if publicBlock == nil {
        panic("public key error")
    }
    pub, err := x509.ParsePKIXPublicKey(publicBlock.Bytes)
    if err != nil {
        panic("publicKey is not  *rsa.PublicKey")
    }
    publicKey := pub.(*rsa.PublicKey)
    rng := rand.Reader

    secretMessage := []byte(plaintext)
    label := []byte(labeltext)
    cipherbyte, err := rsa.EncryptOAEP(sha256.New(), rng, publicKey, secretMessage, label)
    if err != nil {
        panic(fmt.Sprintf("Error from encryption: %s
", err))
    }

    // 由于加密是随机函数,密文将是
    // 每次都不一样。
    //fmt.Printf("Ciphertext: %x
", cipherbyte)
    ciphertext = fmt.Sprintf("%x
", cipherbyte)
    return
}

func RSADecryptOAEP(privateKeypem, labeltext, ciphertext string) (plaintext string) {
    privateBlock, _ := pem.Decode([]byte(privateKeypem))
    if privateBlock == nil {
        panic("private key error")
    }

    privateKey, err := x509.ParsePKCS1PrivateKey(privateBlock.Bytes)
    if err != nil {
        panic("privateKey is not  *rsa.PrivateKey")
    }

    /*
        prkI, err := x509.ParsePKCS8PrivateKey(privateBlock.Bytes)
        if err != nil {
            panic("privateKey is not  *rsa.PrivateKey")
        }
        privateKey := prkI.(*rsa.PrivateKey)
    */
    rng := rand.Reader
    ///
    cipherByte, _ := hex.DecodeString(ciphertext)
    label := []byte(labeltext)

    plainbyte, err := rsa.DecryptOAEP(sha256.New(), rng, privateKey, cipherByte, label)
    if err != nil {
        panic(fmt.Sprintf("Error decrypting: %s
", err))
    }

    // 由于加密是随机函数,密文将是
    // 每次都不一样。
    plaintext = string(plainbyte)
    return
}

func RSAEncryptPKCS1v15(publicKeypem, plaintext string) (ciphertext string) {
    publicBlock, _ := pem.Decode([]byte(publicKeypem))
    if publicBlock == nil {
        panic("public key error")
    }
    pub, err := x509.ParsePKIXPublicKey(publicBlock.Bytes)
    if err != nil {
        panic("publicKey is not  *rsa.PublicKey")
    }
    publicKey := pub.(*rsa.PublicKey)
    plaintbyte := []byte(plaintext)
    blocks := pkcs1Padding(plaintbyte, publicKey.N.BitLen()/8)

    buffer := bytes.Buffer{}
    for _, block := range blocks {
        ciphertextPart, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, block)
        if err != nil {
            panic(fmt.Sprintf("Error EncryptPKCS1v15: %s
", err))
        }
        buffer.Write(ciphertextPart)
    }

    ciphertext = fmt.Sprintf("%x
", buffer.Bytes())
    return
}

func RSADecryptPKCS1v15(privateKeypem, ciphertext string) (plaintext string) {
    privateBlock, _ := pem.Decode([]byte(privateKeypem))
    if privateBlock == nil {
        panic("private key error")
    }

    privateKey, err := x509.ParsePKCS1PrivateKey(privateBlock.Bytes)
    if err != nil {
        panic("privateKey is not  *rsa.PrivateKey")
    }

    /*
        prkI, err := x509.ParsePKCS8PrivateKey(privateBlock.Bytes)
        if err != nil {
            panic("privateKey is not  *rsa.PrivateKey")
        }
        privateKey := prkI.(*rsa.PrivateKey)
    */
    ///
    cipherByte, _ := hex.DecodeString(ciphertext)

    ciphertextBlocks := unPadding(cipherByte, privateKey.N.BitLen()/8)

    buffer := bytes.Buffer{}
    for _, ciphertextBlock := range ciphertextBlocks {
        plaintextBlock, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, ciphertextBlock)
        if err != nil {
            panic(fmt.Sprintf("Error DecryptPKCS1v15: %s
", err))
        }
        buffer.Write(plaintextBlock)
    }

    plaintext = string(buffer.Bytes())
    return
}

func SignPKCS1v15(privateKeypem string, src []byte, hash crypto.Hash) ([]byte, error) {
    privateBlock, _ := pem.Decode([]byte(privateKeypem))
    if privateBlock == nil {
        panic("private key error")
    }

    privateKey, err := x509.ParsePKCS1PrivateKey(privateBlock.Bytes)
    if err != nil {
        panic("privateKey is not  *rsa.PrivateKey")
    }
    h := hash.New()
    h.Write(src)
    hashed := h.Sum(nil)
    return rsa.SignPKCS1v15(rand.Reader, privateKey, hash, hashed)
}

func VerifyPKCS1v15Verify(publicKeypem string, src []byte, sign []byte, hash crypto.Hash) error {
    publicBlock, _ := pem.Decode([]byte(publicKeypem))
    if publicBlock == nil {
        panic("public key error")
    }
    pub, err := x509.ParsePKIXPublicKey(publicBlock.Bytes)
    if err != nil {
        panic("publicKey is not  *rsa.PublicKey")
    }
    publicKey := pub.(*rsa.PublicKey)
    h := hash.New()
    h.Write(src)
    hashed := h.Sum(nil)
    return rsa.VerifyPKCS1v15(publicKey, hash, hashed, sign)
}

func pkcs1Padding(src []byte, keySize int) [][]byte {
    srcSize := len(src)
    blockSize := keySize - 11
    var v [][]byte
    if srcSize <= blockSize {
        v = append(v, src)
    } else {
        groups := len(src) / blockSize
        for i := 0; i < groups; i++ {
            block := src[:blockSize]
            v = append(v, block)
            src = src[blockSize:]
            if len(src) < blockSize {
                v = append(v, src)
            }
        }
    }
    return v
}

func unPadding(src []byte, keySize int) [][]byte {
    srcSize := len(src)
    blockSize := keySize
    var v [][]byte
    if srcSize == blockSize {
        v = append(v, src)
    } else {
        groups := len(src) / blockSize
        for i := 0; i < groups; i++ {
            block := src[:blockSize]

            v = append(v, block)
            src = src[blockSize:]
        }
    }
    return v
}

//RSA公钥私钥产生 GenRsaKey(1024)
func GenRsaKey(bits int) error {
    // 生成私钥文件
    privateKey, err := rsa.GenerateKey(rand.Reader, bits)
    if err != nil {
        return err
    }
    derStream := x509.MarshalPKCS1PrivateKey(privateKey)
    block := &pem.Block{
        Type:  "RSA PRIVATE KEY",
        Bytes: derStream,
    }
    file, err := os.Create("private.pem")
    if err != nil {
        return err
    }
    err = pem.Encode(file, block)
    if err != nil {
        return err
    }
    // 生成公钥文件
    publicKey := &privateKey.PublicKey
    derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
    if err != nil {
        return err
    }
    block = &pem.Block{
        Type:  "PUBLIC KEY",
        Bytes: derPkix,
    }
    file, err = os.Create("public.pem")
    if err != nil {
        return err
    }
    err = pem.Encode(file, block)
    if err != nil {
        return err
    }
    return nil

}

使用如下:

pirvatekey := "-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDXmqwFmi9TPVL1NgYZgGaHdPz7ZsskAOukaYg/hZkAn4rj8JJcaE/DzRy707bq6YBUpp+1ssiaadJRKR6+XMSzdyJz44Vl5rrArExrzGiNry+txRVo00U4xbIrmMX+aRKvPQ/xJ7xkxRhdxsY4F/wMcWDyJS+eyxJkHiBrHJ3ciQIDAQABAoGBAJV7eZUQx4sQ03mLkUMREQUNiXDMXj+CG96MBJj2CZSzCNrsqq1C7Tq19RwMt5+7cOw/8i9J22ejwtvehKA7NWxpsUBC+lDqXk3FCvtbL3d2fcARdh/1zWZN9WRvafkVPNPAeRC6ARp63DOe8FkT0C22DTOd0Xyvo0Zp7pF/GjXhAkEA/BkAFlV/4jHEglyXHNGrReMjClw2ClqKK5VXIk6UCJfVaGNDGbfw0ueYFnnOeIo8GPhgVjSC4wU2rX89pSFxTQJBANrxDqKc6wFw1jGpmxI25inxYTvA3SuSk36b4CSrRL7w3g9r+6QQfAlpBRZ9NBCL9WHeWHtgauxeDGJB2kmXui0CQQDhadlSHxFCSA3WIsRb2H609uwWD22ixGJXpilLW8eyB1GjDV6qWHbVno+3SSL9VV13Vl+NtVZzd+30JJoSVVzhAkB8sISxP8TnUSfrqLhUK0fx4zKJIVHUmum9VXDV8WR5ihwtlEYALhM2GMV5BV09fzgEwOiLe2Hps7ZBz1dOSkcRAkEA+D3kzvNpEYtqpjGHfUCxwmu/BwathDo09vj+gCcjhoJh/ADpa8+a0RQA6vcVMges0UcmIiIyQPNzCGlLBXtl9A==
-----END RSA PRIVATE KEY-----"
    pubKey := "-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXmqwFmi9TPVL1NgYZgGaHdPz7ZsskAOukaYg/hZkAn4rj8JJcaE/DzRy707bq6YBUpp+1ssiaadJRKR6+XMSzdyJz44Vl5rrArExrzGiNry+txRVo00U4xbIrmMX+aRKvPQ/xJ7xkxRhdxsY4F/wMcWDyJS+eyxJkHiBrHJ3ciQIDAQAB
-----END PUBLIC KEY-----"

    label := "orders"
    plaintext := "send reinforcements, we're going to advance"

    ciphertext := utils.RSAEncryptOAEP(pubKey, label, plaintext)
    fmt.Println(ciphertext)
    plaintext = utils.RSADecryptOAEP(pirvatekey, label, ciphertext)
    fmt.Println(plaintext)

    ciphertext = utils.RSAEncryptPKCS1v15(pubKey, plaintext)
    fmt.Println(ciphertext)
    plaintext = utils.RSADecryptPKCS1v15(pirvatekey, ciphertext)
    fmt.Println(plaintext)

    //签名 和验证
    signBytes, err := utils.SignPKCS1v15(pirvatekey, []byte(plaintext), crypto.SHA256)
    if err != nil {
        fmt.Println("SignPKCS1v15 error")
    }
    fmt.Println("SignPKCS1v15 base64:" + base64.StdEncoding.EncodeToString(signBytes))
    err = utils.VerifyPKCS1v15Verify(pubKey, []byte(plaintext), signBytes, crypto.SHA256)
    if err == nil {
        fmt.Println("VerifyPKCS1v15Verify oaky")
    }

需要引入相应的包:

import (
    "crypto"
    "demo/utils"
    "encoding/base64"
    "fmt"
)

上面的publickey private可以 是通过utils.GenRsaKey(1024) 文件生成的,注意 -----BEGIN RSA PRIVATE KEY----- 后面有一个 后面结束的时候也有这个

原文地址:https://www.cnblogs.com/majiang/p/14163614.html