osnosn

  博客园 :: 首页 :: 博问 :: 闪存 :: :: 联系 :: 订阅 订阅 :: 管理 ::

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\n", 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\n", pubkey.N.BitLen())
        fmt.Printf("E:%x\nN:%x\n", 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\n", hex.EncodeToString(data))
        fmt.Println("------rsa encrypt nopadding-------")
        txt = RsaEncryptNopadding(pubkey, []byte(cleartxt))
        fmt.Printf("=> %s\n", txt)
        fmt.Println("------rsa encrypt oaep-------")
        txt = RsaEncryptOAEP(pubkey, cleartxt)
        fmt.Printf("=> %s\n", txt)

        fmt.Println("------pubkey from N,E:-------")
        N := "b54a4cf3c2ceb6d34f6c45797528174901075fad452e7f0787ff82da82bd4f056685ad3c26fbd34e837c26792e100f29d065aa2a5c3a6222179d67df127038223ac7dd74a1f17f58b905702291273d8df12971692c4329225978839b32f08d299a770c1b60334f5ab7322f7cc90fc20f71c7aee0646e8ccfa7766bcde4db4087"
        E := "10001"
        pubkey, _ = readNE(N, E)
        //fmt.Println(pubkey)
        fmt.Printf("BitLen:%d\n", 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\n", hex.EncodeToString(data))
        fmt.Println("------rsa encrypt nopadding-------")
        txt = RsaEncryptNopadding(pubkey, []byte(cleartxt))
        fmt.Printf("=> %s\n", txt)
        fmt.Println("------rsa encrypt oaep-------")
        txt = RsaEncryptOAEP(pubkey, cleartxt)
        fmt.Printf("=> %s\n", txt)

        pubkey_to_pem(pubkey, "out_pubkey.pem")

        fmt.Printf("--- Finished ---\n")
}
  • 执行结果
------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/ .


posted on 2021-09-13 17:39  osnosn  阅读(176)  评论(0编辑  收藏  举报