我有一个场景,我需要将 RSA公钥加密标准与 JavaScript 和 Golang 一起使用。 我需要使用公钥在JavaScript中加密数据,并使用私钥在Golang中对其进行解密。 我尝试使用 PKCS#1(用于JavaScript的travst库和用于Golang的crypto / rsa),但在解密时失败了。有人可以为此提出解决方案吗?
我尝试了所有可能的解决方案并研究了很多文档,但我仍然无法找到合适的方法。如果我在golang中加密和解密,它的工作正常。但是javascript和golang之间存在一些集成问题。我不确定javasript中使用的填充方法。
这是我要解密的golang代码:
func Decrypt(encryptedData, label []byte) (decryptedData []byte) {
var err error
var block *pem.Block
var private_key *rsa.PrivateKey
if 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 Key
if private_key, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
log.Fatalf("Private key can't be decoded: %s", err)
}
//Decrypt
if decrypted, err = rsa.DecryptPKCS1v15(rand.Reader, private_key, encryptedData); err != nil {
log.Println(err)
}
return
}
答案 0 :(得分:2)
可以在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 { ... }
答案 1 :(得分:1)
1:您可以从javascript参考中加密明文。
var encrypt = new JSEncrypt();
encrypt.setPublicKey($('#pubkey').val());
var encrypted = encrypt.encrypt($('#input').val());
2:请注意,jsencrypt已经完成了加密和base64encode。
请注意,jsencrypt使用PKCS1而不是OAEP
3:golang中的Base64解码并解密第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
来自
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
}