zoukankan      html  css  js  c++  java
  • 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----- 后面有一个 后面结束的时候也有这个

  • 相关阅读:
    ASP.NET 2.0 中改进的缓存功能
    Python 一门神奇的语言
    showModalDialog()、showModelessDialog()方法使用详解
    在VS2005中 GridView导入Excel的两点小技巧附源码
    DVB码流中业务信息与电子节目指南
    js 日历控件
    js收藏
    什么是ECM,EMM,AU,EMU?
    精解PSISI(一)
    Oracle第四课(学习笔记)
  • 原文地址:https://www.cnblogs.com/majiang/p/14163614.html
Copyright © 2011-2022 走看看