为了账号安全,请及时绑定邮箱和手机立即绑定

RSA Javascript 加密和 Golang 解密

RSA Javascript 加密和 Golang 解密

Go
牧羊人nacy 2021-12-27 10:33:27
我有一种情况,我需要使用RSA公共密钥加密标准用的JavaScript和Golang。我需要使用公钥在 JavaScript 中加密数据,并使用私钥在 Golang 中解密数据。我尝试使用PKCS#1(travst library for JavaScript and crypto/rsa for Golang),但解密失败。任何人都可以为此提出解决方案吗?我尝试了所有可能的解决方案并研究了许多文档,但仍然找不到合适的方法。如果我在 golang 中加密和解密,它工作正常。但是javascript和golang之间存在一些集成问题。我不确定 javasript 中使用的填充方法。这是我要解密的golang代码:func Decrypt(encryptedData, label []byte) (decryptedData []byte) {var err errorvar block *pem.Blockvar private_key *rsa.PrivateKeyif block, _ = pem.Decode([]byte(privatKeyData)); block == nil || block.Type != "RSA PRIVATE KEY" { //privatKeyData is in string format    log.Fatal("No valid PEM data found")}//Read Private Keyif private_key, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {    log.Fatalf("Private key can't be decoded: %s", err)}//Decryptif decrypted, err = rsa.DecryptPKCS1v15(rand.Reader, private_key, encryptedData); err != nil {        log.Println(err)}return}
查看完整描述

2 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

可以在 javascript 中加密并在 Go 中解密。使用您引用的库jsencrypt:


创建公私钥对:


openssl genrsa -out key.pem

openssl rsa -in key.pem -pubout > pub.pem

javascript中的加密:


var encrypt = new JSEncrypt();

encrypt.setPublicKey($('#pubkey').val());


var encrypted = encrypt.encrypt($('#message').val());


$.post("/decrypt", encrypted, function(response) {

    $("#decrypted").val(response);

});

Go中的解密:


func handleDecrypt(w http.ResponseWriter, r *http.Request) {

    decoder := base64.NewDecoder(base64.StdEncoding, r.Body)

    defer r.Body.Close()

    encrypted, err := ioutil.ReadAll(decoder)

    if err != nil {

        http.Error(w, err.Error(), http.StatusBadRequest)

        return

    }

    data, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, encrypted)

    if err != nil {

        http.Error(w, "decrypt error", http.StatusBadRequest)

        log.Println(err)

        return

    }

    fmt.Fprint(w, string(data))

}

更新:privateKey 变量是从 openssl 创建的私钥文件派生的 *rsa.PrivateKey,在本例中为“key.pem”文件。pem 文件是 Base64 编码的 DER 证书,例如 -----BEGIN RSA PRIVATE KEY----- 和 -----END RSA PRIVATE KEY----- 以 PEM 格式显示私钥。Go 标准库提供了x509.ParsePKCS1PrivateKey()方法来从字节切片解析 pem 编码的密钥。


因此,将密钥加载到 Go 中可能看起来像这样:


keyBytes, err := ioutil.ReadFile("path/to/key.pem")

if err != nil { ... }


privateKey, err := x509.ParsePKCS1PrivateKey(keyBytes)

if err != nil { ... }


查看完整回答
反对 回复 2021-12-27
?
富国沪深

TA贡献1790条经验 获得超9个赞

1:您可以从javascript参考中加密明文。


https://github.com/travist/jsencrypt


var encrypt = new JSEncrypt();

encrypt.setPublicKey($('#pubkey').val());

var encrypted = encrypt.encrypt($('#input').val());

2:注意jsencrypt已经做了加密和base64encode。


请注意 jsencrypt 使用 PKCS1 而不是 OAEP


3:在 golang 中进行 Base64decode 并解密来自步骤 1 的消息。


var encrypted := 'change this to the encrypted text your js sent'

privateKey,_ = ioutil.ReadFile("private.pem")

cipherText,_ := base64.StdEncoding.DecodeString(encrypted)

originText,_ :=RsaDecrypt([]byte(cipherText))

解密函数


func RsaDecrypt(cipherText []byte) ([]byte, error) {

        block, _ := pem.Decode(privateKey)

        if block == nil {

            return nil, errors.New("private key error!")

        }

        priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)

        if err != nil {

            return nil, err

        }


        return rsa.DecryptPKCS1v15(rand.Reader, priv, cipherText)

    }

现在您originText 从


https://segmentfault.com/q/1010000002505932


4:更进一步,你可以在go中生成密钥对


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:  "privete 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

}


查看完整回答
反对 回复 2021-12-27
  • 2 回答
  • 0 关注
  • 424 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信