• RSA.js_公钥加密_NoPadding_golang实现_n_e_pem格式互转


    RSA.js_公钥加密_NoPadding_golang实现_n_e_pem格式互转

    转载注明来源: 本文链接 来自osnosn的博客,写于 2021-09-13.

    参考

    openssl 生成 rsa 密钥对

    • 生成rsa私钥,openssl genrsa -out rsakey.pem 1024
    • 生成rsa公钥,openssl rsa -in rsakey.pem -pubout -out rsapubkey.pem

    golang 例子

    • 其中 RsaEncryptNopadding() 的加密结果,
      对比 JavaScript 中, 用 Barrett.js, BigInt.js, RSA.js (Copyright 1998-2005 David Shapiro.) 脚本加密的结果相同。
    • 新版的 RSA.js 已经支持 PKCS1v1.5 的 padding 了。就不需要这种 nopadding 的算法了。用 RsaEncryptPkcs1( )。
    • RsaEncryptOAEP( ) , OAEP 方式。
    • 例程中演示了,读入 PEM 格式公钥,输出 N, E。
    • readNE( ) 和 pubkey_to_pem( ) , 可以实现公钥 N, E 转为 PEM 格式。
    package main
    
    import (
            "crypto/rand"
            "crypto/rsa"
            "crypto/sha1"
            "crypto/x509"
            "encoding/hex"
            "encoding/pem"
            "errors"
            "fmt"
            "io/ioutil"
            "math/big"
            "net/url"
            "os"
            "strconv"
            "strings"
    )
    
    func readPEM(file string) (*rsa.PublicKey, error) {
            // 读取公匙文件
            pubByte, err := ioutil.ReadFile(file)
            if err != nil {
                    return nil, err
            }
            // pem解码
            block, _ := pem.Decode(pubByte)
            if block == nil {
                    return nil, errors.New("error public key")
            }
            // 解析公钥
            pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
            if err != nil {
                    return nil, err
            }
            // 类型断言
            pubkey := pubInterface.(*rsa.PublicKey)
            return pubkey, nil
    }
    func readNE(N string, E string) (*rsa.PublicKey, error) {
            // 另一种创建pubkey的方法
            E64, _ := strconv.ParseInt(E, 16, 32)
            Eint := int(E64)
            bigN := new(big.Int)
            _, ok := bigN.SetString(N, 16)
            if !ok {
                    panic("failed to parse")
            }
            pubkey := &rsa.PublicKey{
                    N: bigN,
                    E: Eint,
            }
            return pubkey, nil
    }
    
    func RsaEncryptPkcs1(pubkey *rsa.PublicKey, origData []byte) ([]byte, error) {
            //加密
            return rsa.EncryptPKCS1v15(rand.Reader, pubkey, origData)
    }
    func RsaEncryptNopadding(pubkey *rsa.PublicKey, origData []byte) string {
            //反转明文
            for from, to := 0, len(origData)-1; from < to; from, to = from+1, to-1 {
                    origData[from], origData[to] = origData[to], origData[from] //反转字符串
            }
            //加密,这里需要判断 len(明文)<=(N.BitLen()/8-2), 否则就要分组加密。(本例程未作判断)
            c := new(big.Int).SetBytes(origData)
            encryptedBytes := c.Exp(c, big.NewInt(int64(pubkey.E)), pubkey.N).Bytes()  // c的E次方 mod N
            encryptedHex := hex.EncodeToString(encryptedBytes)
            return encryptedHex
    }
    func RsaEncryptOAEP(pubkey *rsa.PublicKey, text string) string {
            secretMessage := []byte(text)
            rng := rand.Reader
            cipherdata, err := rsa.EncryptOAEP(sha1.New(), rng, pubkey, secretMessage, nil)
            if err != nil {
                    fmt.Printf("Error from encryption: %s
    ", err)
                    return ""
            }
            return hex.EncodeToString(cipherdata)
    }
    func pubkey_to_pem(pubkey *rsa.PublicKey, outfilename string) {
            //输出pem格式的公钥
            derPubkey, _ := x509.MarshalPKIXPublicKey(pubkey)
            block := &pem.Block{
                    Type:  "PUBLIC KEY",
                    Bytes: derPubkey,
            }
            pemfile, _ := os.Create(outfilename)
            _ = pem.Encode(pemfile, block)
            pubkey_b := pem.EncodeToMemory(block)
            fmt.Println(string(pubkey_b))
    }
    func encodeURIComponent(str string) string {
            //JavaScript 的 encodeURIComponent()
            r := url.QueryEscape(str)
            r = strings.Replace(r, "+", "%20", -1)
            return r
    }
    func main() {
            var pubkey *rsa.PublicKey
            var cleartxt, txt string
            var data []byte
            fmt.Println("------pubkey from pem-------")
            pubkey, _ = readPEM("rsapubkey.pem")
            fmt.Printf("BitLen:%d
    ", pubkey.N.BitLen())
            fmt.Printf("E:%x
    N:%x
    ", pubkey.E, pubkey.N.Bytes())
    
            cleartxt = "abcdefg12345" //明文
            fmt.Println("Clear text:", cleartxt)
            fmt.Println("------rsa encrypt pkcs1-------")
            data, _ = RsaEncryptPkcs1(pubkey, []byte(cleartxt))
            fmt.Printf("=> %s
    ", hex.EncodeToString(data))
            fmt.Println("------rsa encrypt nopadding-------")
            txt = RsaEncryptNopadding(pubkey, []byte(cleartxt))
            fmt.Printf("=> %s
    ", txt)
            fmt.Println("------rsa encrypt oaep-------")
            txt = RsaEncryptOAEP(pubkey, cleartxt)
            fmt.Printf("=> %s
    ", txt)
    
            fmt.Println("------pubkey from N,E:-------")
            N := "b54a4cf3c2ceb6d34f6c45797528174901075fad452e7f0787ff82da82bd4f056685ad3c26fbd34e837c26792e100f29d065aa2a5c3a6222179d67df127038223ac7dd74a1f17f58b905702291273d8df12971692c4329225978839b32f08d299a770c1b60334f5ab7322f7cc90fc20f71c7aee0646e8ccfa7766bcde4db4087"
            E := "10001"
            pubkey, _ = readNE(N, E)
            //fmt.Println(pubkey)
            fmt.Printf("BitLen:%d
    ", pubkey.N.BitLen())
    
            cleartxt = encodeURIComponent("abcdefg12345") //明文,且url编码
            fmt.Println("Clear text:", cleartxt)
            fmt.Println("------rsa encrypt pkcs1-------")
            data, _ = RsaEncryptPkcs1(pubkey, []byte(cleartxt))
            fmt.Printf("=> %s
    ", hex.EncodeToString(data))
            fmt.Println("------rsa encrypt nopadding-------")
            txt = RsaEncryptNopadding(pubkey, []byte(cleartxt))
            fmt.Printf("=> %s
    ", txt)
            fmt.Println("------rsa encrypt oaep-------")
            txt = RsaEncryptOAEP(pubkey, cleartxt)
            fmt.Printf("=> %s
    ", txt)
    
            pubkey_to_pem(pubkey, "out_pubkey.pem")
    
            fmt.Printf("--- Finished ---
    ")
    }
    
    • 执行结果
    ------pubkey from pem-------
    BitLen:1024
    E:10001
    N:b54a4cf3c2ceb6d34f6c45797528174901075fad452e7f0787ff82da82bd4f056685ad3c26fbd34e837c26792e100f29d065aa2a5c3a6222179d67df127038223ac7dd74a1f17f58b905702291273d8df12971692c4329225978839b32f08d299a770c1b60334f5ab7322f7cc90fc20f71c7aee0646e8ccfa7766bcde4db4087
    Clear text: abcdefg12345
    ------rsa encrypt pkcs1-------
    => 288263e8104bbe9f735bdc7a4403c28293084ea10adc1b0ad9ea285f003b1857cdbb90f900570fbfc06645fdadf644474607e5d71bfb3fd83346f67777d4fdc0ca0c081aaeb6a3b3540e3823c633ce77bb75169f92611dee5949fd84f0d5c3c1ad8bf85892307f076ff71ca35ea66516ff13a17e1feb2d4a37941e71cf6720eb
    ------rsa encrypt nopadding-------
    => 3795065bad6c9a54a3b7b558d64c75bf7236fc4e9c67503e2343d9e5c07b72540ce620e0962a968fe0a89e54aee0572582d50c97535e8e0e6bb2841e4f6465cbfbe779ad30aa6396e47a3157a2c01a9845f91d1c771468a3088c2fd776027c64ce767009096a91d5b65e9c4defab8c6b5713ced1266fd8a3679d9d1a35737d69
    ------rsa encrypt oaep-------
    => b480eb91196fa9f695aaf065658d56c2982dcfd56e323c2e061060c10cc0128541ec22943919c9c23a8a276d0a8450979a651450ee3f0d3252a9eae6803926ebd2e36c30593e8265b1119b74c9a37f940b8217551d573d1b8a71982e7a0929db4c8f0fc0cfbf4aff575e62c735db89e36f1453d01c123963459aa08c36f83516
    ------pubkey from N,E:-------
    BitLen:1024
    Clear text: abcdefg12345
    ------rsa encrypt pkcs1-------
    => 1959688e94ddaae83c83ae6ef531df1ac4eb142e2ca284501fe83b532297ddfb1f31d346fa88bcc59b368b9f5ec7f04a7693c6a022109a8fb861499059aacce4fd1ddc2908139102f9cc8948312f5f187c7d9bbf29c32bae71b4e0362f06f374f25f2396cbc91c760230911eae71416a51d0f6bacbe050663ba664d997e86648
    ------rsa encrypt nopadding-------
    => 3795065bad6c9a54a3b7b558d64c75bf7236fc4e9c67503e2343d9e5c07b72540ce620e0962a968fe0a89e54aee0572582d50c97535e8e0e6bb2841e4f6465cbfbe779ad30aa6396e47a3157a2c01a9845f91d1c771468a3088c2fd776027c64ce767009096a91d5b65e9c4defab8c6b5713ced1266fd8a3679d9d1a35737d69
    ------rsa encrypt oaep-------
    => a76804bef115d34a16fe81017e746f24c9e09da7cc2a24316980f6d265c66a212b0933c6d83915240894eb8c55dde77efb71f14ca147a5083962888ae4e90944d2c165da23116f03f6db7acbe78b51e5b8ca464aef3d81458263df5767b01ae683c6c2806424db61f750a345fb4e08e27ca087e40ca05403ae1dd63835c27784
    -----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1Skzzws62009sRXl1KBdJAQdf
    rUUufweH/4Lagr1PBWaFrTwm+9NOg3wmeS4QDynQZaoqXDpiIhedZ98ScDgiOsfd
    dKHxf1i5BXAikSc9jfEpcWksQykiWXiDmzLwjSmadwwbYDNPWrcyL3zJD8IPcceu
    4GRujM+ndmvN5NtAhwIDAQAB
    -----END PUBLIC KEY-----
    
    --- Finished ---
    

    python3, N E 转 pem

    #!/usr/bin/python3
    # -*- coding: utf-8 -*- #
    
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives.asymmetric import rsa
    from cryptography.hazmat.primitives import serialization
    
    exponent=0x10001
    modulus="b54a4cf3c2ceb6d34f6c45797528174901075fad452e7f0787ff82da82bd4f056685ad3c26fbd34e837c26792e100f29d065aa2a5c3a6222179d67df127038223ac7dd74a1f17f58b905702291273d8df12971692c4329225978839b32f08d299a770c1b60334f5ab7322f7cc90fc20f71c7aee0646e8ccfa7766bcde4db4087"
    
    def populate_public_key(modulus, exponent):
        n=int(modulus,16)
        e=exponent
        key=rsa.RSAPublicNumbers(e,n).public_key(default_backend())
        return key
    def generate_pub_key(pub_key, pem_name):
        pem=pub_key.public_bytes(
                encoding=serialization.Encoding.PEM,
                format=serialization.PublicFormat.SubjectPublicKeyInfo
                )
        print(pem.decode())
        #with open(pem_name,'w+') as f:
        #    f.writelines(pem.decode())
        return pem
    if __name__=='__main__':
        pub_key=populate_public_key(modulus,exponent)
        pem_file=r'pub_key.pem'
        generate_pub_key(pub_key,pem_file)
    

    转载注明来源: 本文链接 https://www.cnblogs.com/osnosn/p/15262557.html
    来自 osnosn的博客 https://www.cnblogs.com/osnosn/ .


  • 相关阅读:
    LabVIEW-水仙花数
    NRF51822自学笔记(一) 流水灯
    机器学习第四次作业
    4.K均值算法--应用
    机器学习第三次
    机器学习第二次专业
    算符优先分析
    自下而上语法分析
    递归下降语法分析
    LL(1)文法的判断,递归下降分析程序
  • 原文地址:https://www.cnblogs.com/osnosn/p/15262557.html
Copyright © 2020-2023  润新知