zoukankan      html  css  js  c++  java
  • 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/ .


  • 相关阅读:
    javaweb消息中间件——rabbitmq入门
    virtual box 桥接模式(bridge adapter)下无法获取ip(determine ip failed)的解决方法
    Apache Kylin本地启动
    git操作
    Java学习总结
    Java中同步的几种实现方式
    hibernate exception nested transactions not supported 解决方法
    vue 中解决移动端使用 js sdk 在ios 上一直报invalid signature 的问题解决
    cookie 的使用
    vue 专门为了解决修改微信标题而生的项目
  • 原文地址:https://www.cnblogs.com/osnosn/p/15262557.html
Copyright © 2011-2022 走看看