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] //&#x53CD;&#x8F6C;&#x5B57;&#x7B26;&#x4E32;
        }
        //&#x52A0;&#x5BC6;,&#x8FD9;&#x91CC;&#x9700;&#x8981;&#x5224;&#x65AD; len(&#x660E;&#x6587;)<=(n.bitlen() 8-2), 否则就要分组加密。(本例程未作判断) c :="new(big.Int).SetBytes(origData)" encryptedbytes big.newint(int64(pubkey.e)), pubkey.n).bytes() c的e次方 mod n encryptedhex return } func rsaencryptoaep(pubkey *rsa.publickey, text string) string { secretmessage rng cipherdata, err rng, pubkey, secretmessage, nil) if !="nil" fmt.printf("error from encryption: %s\n", err) "" hex.encodetostring(cipherdata) pubkey_to_pem(pubkey outfilename 输出pem格式的公钥 derpubkey, _ block type: "public key", bytes: pemfile, block) pubkey_b fmt.println(string(pubkey_b)) encodeuricomponent(str javascript 的 encodeuricomponent() r "+", "%20", -1) main() var pubkey *rsa.publickey cleartxt, txt data []byte fmt.println("------pubkey 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, []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") //&#x660E;&#x6587;,&#x4E14;url&#x7F16;&#x7801;
        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")
}
</=(n.bitlen()>
  • 执行结果

`
=> 288263e8104bbe9f735bdc7a4403c28293084ea10adc1b0ad9ea285f003b1857cdbb90f900570fbfc06645fdadf644474607e5d71bfb3fd83346f67777d4fdc0ca0c081aaeb6a3b3540e3823c633ce77bb75169f92611dee5949fd84f0d5c3c1ad8bf85892307f076ff71ca35ea66516ff13a17e1feb2d4a37941e71cf6720eb
=> b480eb91196fa9f695aaf065658d56c2982dcfd56e323c2e061060c10cc0128541ec22943919c9c23a8a276d0a8450979a651450ee3f0d3252a9eae6803926ebd2e36c30593e8265b1119b74c9a37f940b8217551d573d1b8a71982e7a0929db4c8f0fc0cfbf4aff575e62c735db89e36f1453d01c123963459aa08c36f83516
=> 1959688e94ddaae83c83ae6ef531df1ac4eb142e2ca284501fe83b532297ddfb1f31d346fa88bcc59b368b9f5ec7f04a7693c6a022109a8fb861499059aacce4fd1ddc2908139102f9cc8948312f5f187c7d9bbf29c32bae71b4e0362f06f374f25f2396cbc91c760230911eae71416a51d0f6bacbe050663ba664d997e86648
=> a76804bef115d34a16fe81017e746f24c9e09da7cc2a24316980f6d265c66a212b0933c6d83915240894eb8c55dde77efb71f14ca147a5083962888ae4e90944d2c165da23116f03f6db7acbe78b51e5b8ca464aef3d81458263df5767b01ae683c6c2806424db61f750a345fb4e08e27ca087e40ca05403ae1dd63835c27784

Original: https://www.cnblogs.com/osnosn/p/15262557.html
Author: osnosn
Title: RSA.js_公钥加密_NoPadding_golang实现_n_e_pem格式互转

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/516602/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球