简体   繁体   English

从Java到NodeJS的RSA公钥

[英]RSA Public Key from Java into NodeJS

I'm having some trouble with using a public key from Java to encrypt within NodeJS. 使用Java的公共密钥在NodeJS中进行加密时遇到了一些麻烦。

I've created an RSA key within keytool and output the public key as a base64 encoded string. 我已经在keytool创建了一个RSA密钥,并将公共密钥输出为base64编码的字符串。

Base64.Encoder encoder = Base64.getEncoder();
byte[] pubKeyBytes = publicKey.getEncoded();
String pubKeyBase64 = encoder.encodeToString(pubKeyBytes);

I then took the the base64 encoded public key, wrapped it in -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- and used it to encrypt, then base64 encode a string within node. 然后,我获取了base64编码的公钥,将其包装在-----BEGIN PUBLIC KEY----------END PUBLIC KEY-----并用它进行加密,然后base64对一个节点内的字符串。

const encryptedBuffer = crypto.publicEncrypt(encodedPublicKey, buffer);
const encryptedEncodedText = encryptedBuffer.toString("base64");

When I try to decrypt the encryptedEncodedText (base64 decoding first) within Java, it throws a BadPadding exception. 当我尝试在Java中解密encryptedEncodedText (首先进行base64解码)时,它将引发BadPadding异常。 Interestingly, if I export the private key to a PEM, Node can't decrypt with it either. 有趣的是,如果我将私钥导出到PEM,Node也无法对其进行解密。

Any help would be appreciated! 任何帮助,将不胜感激!

After much searching and testing, it turned out to be a padding issue. 经过大量搜索和测试,结果发现这是一个填充问题。

The public key provided to Node did was not being passed a passphrase, so it defaulted to RSA_PKCS1_OAEP_PADDING as per the documentation: 提供给Node的公钥没有被传递密码,因此根据文档,它默认为RSA_PKCS1_OAEP_PADDING

crypto.publicEncrypt crypto.publicEncrypt

When decrypting on the Java side, it is necessary to inform Java of that padding as follows: 在Java端解密时,有必要按如下方式通知Java该填充:

Cipher cipher = Cipher.getInstance("RSA/NONE/OAEPPadding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);

This fixed the issue, and allowed messages to be exchanged between Java and NodeJS. 这解决了该问题,并允许在Java和NodeJS之间交换消息。

I tried to reproduce your problem. 我试图重现您的问题。 For me, it works fine. 对我来说,效果很好。 I suspect the only problematic step can be when you are creating the PEM file manually. 我怀疑唯一有问题的步骤可能是在手动创建PEM文件时。 Be sure to: 务必:

  • If you are copying the key string from any console, remove unwanted characters from the beginning and/or end. 如果要从任何控制台复制密钥字符串,请从开头和/或结尾删除不需要的字符。
  • And a new line character ( \\n ) after -----BEGIN PUBLIC KEY----- and before -----END PUBLIC KEY----- . -----BEGIN PUBLIC KEY----------END PUBLIC KEY-----之前加上换行符( \\n )。

like below: 如下所示:

var key = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqwEldwNI5s1LkUzwyQZkPQQFpgtj29W7RcHgdwAbUOe31Q8bybAgzg5cUMqdIQlQHq6S5dxsSJBTDCZozSu+pxtKqRLz0JjtCTZD5gS+CJR9DlXH5GgJt+KDiO6olbKiVsP/tsMPgRCFKUMiMKU+dA06dwrUqJlC1k/JzuYVrbwIDAQAB\n-----END PUBLIC KEY-----"

var plaintext = "hello world"
var buffer = new Buffer(plaintext, "utf8")
console.log(crypto.publicEncrypt(key, buffer))

To avoid all these issues, you can directly generate PEM file from Java using the bouncycastle library . 为了避免所有这些问题,您可以使用bouncycastle库直接从Java生成PEM文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM