如何在 Node.js 中使用公钥加密数据?

发布于 2024-12-10 05:54:10 字数 76 浏览 6 评论 0原文

加密中,我只看到用于进行数字签名的签名者/验证者和使用对称密钥加密的密码/解密。

如何使用公钥加密数据?

In crypto, I see only Signer/Verifier for doing digital signature and Cipher/Decipher with symmetric key encryption.

How do I encrypt data with public key?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

安稳善良 2024-12-17 05:54:10

正如官方 Nodejs api 文档中所述:
crypto.publicEncrypt(key, buffer)

使用密钥加密缓冲区的内容,并返回一个包含加密内容的新缓冲区。返回的数据可以使用相应的私钥进行解密,例如使用crypto.privateDecrypt()。

如果 key 不是 KeyObject,则此函数的行为就像 key 已是
传递给 crypto.createPublicKey()。如果它是一个对象,则填充
属性可以传递。否则,该函数使用
RSA_PKCS1_OAEP_PADDING。

因为 RSA 公钥可以从私钥派生,所以私钥
可以传递密钥而不是公钥。

所以答案是:

var encrypted = crypto.publicEncrypt(publicKey, buffer);

As mentioned in the official nodejs api docs here:
crypto.publicEncrypt(key, buffer)

Encrypts the content of buffer with key and returns a new Buffer with encrypted content. The returned data can be decrypted using the corresponding private key, for example using crypto.privateDecrypt().

If key is not a KeyObject, this function behaves as if key had been
passed to crypto.createPublicKey(). If it is an object, the padding
property can be passed. Otherwise, this function uses
RSA_PKCS1_OAEP_PADDING.

Because RSA public keys can be derived from private keys, a private
key may be passed instead of a public key.

So the answer is:

var encrypted = crypto.publicEncrypt(publicKey, buffer);
豆芽 2024-12-17 05:54:10

您可能对我的NaCl 绑定感兴趣。从它的 API 来看:

// Encrypt and sign
box(message, nonce, pubkey, privkey)

// Decrypt and validate
unbox(box, nonce, pubkey, privkey)
// Generates a new keypair, returns {private: <buffer>, public: <buffer>}
boxKeypair()

// Lengths of nonces and public and private keys in bytes
// { nonce: x, pubkey: x, privkey: x }
lengths.box

You might be interested in my NaCl bindings. From its API:

// Encrypt and sign
box(message, nonce, pubkey, privkey)

// Decrypt and validate
unbox(box, nonce, pubkey, privkey)
// Generates a new keypair, returns {private: <buffer>, public: <buffer>}
boxKeypair()

// Lengths of nonces and public and private keys in bytes
// { nonce: x, pubkey: x, privkey: x }
lengths.box
凯凯我们等你回来 2024-12-17 05:54:10

另一种方法是使用加密消息语法 (CMS)。它不是一个纯粹的 Node.js 解决方案,但您可能已经拥有所需的所有工具。下面是使用 OpenSSL 的示例:

生成 x509 证书(收件人)和私钥文件(在 Bash 中):

openssl req  -nodes -new -x509  -keyout key.pem -out cert.pem

从标准输入加密/解密消息(在 Bash 中):

 echo 123 | openssl cms -encrypt -recip cert.pem | openssl cms -decrypt -inkey key.pem

您可以使用 -in/-out 参数来处理文件。以下是可用于 Node.js 的示例:

require('child_process').execSync("openssl cms -encrypt -in file.json -recip cert.pem -out file.json.cms")

在 Linux 上,您可能已经安装了 OpenSSL。您可以通过安装 Git Bash 在 Windows 上获取 OpenSSL,尽管您可以还可以使用内置的 PowerShell 命令。您需要生成 PFX 证书(使用New- SelfSignedCertificate)或安装现有证书(也可以使用 OpenSSL 生成)。将证书安装到证书存储中后,您可以使用以下命令进行加密/解密:

Protect-CmsMessage -to CN=MyCertName -Path file.json -OutFile file.json.cms
Unprotect-CmsMessage -Path file.json # It will find proper cert in cert store for you

下面是如何使用 OpenSSL 从同一私钥生成 .pem 和 PFX 证书的示例,并使消息在 OpenSSL 和 PowerShell 之间可互换。

生成带有扩展名的证书(Windows 上需要):

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout key.pem -out cert.pem -subj '/CN=MyCertName' -addext extendedKeyUsage=1.3.6.1.4.1.311.80.1 -addext keyUsage=keyEncipherment

上面的代码片段仅适用于较新版本的 OpenSSL (1.1.1)。否则,您需要一个单独的文件来定义扩展。然后生成 PFX 证书(使用一些密码保护它):

openssl pkcs12 -export -out certificate.pfx -inkey key.pem -in cert.pem -passout pass:P@ssw0rd

然后将该 PFX 文件复制到您的 Windows 计算机。您应该能够通过 PowerShell (Import-PfxCertificate) 或手动安装(单击它并按照向导操作,使用所有默认值)。为了使消息可互换,请在使用 OpenSSL 时使用 -inform \ -outform 参数。例如:

openssl cms -encrypt -in file.json -recip cert.pem -outform PEM 
openssl cms -decrypt -in file.json.cms -inkey key.pem -inform PEM
# If having both OpenSSL/PowerShell on the same OS, use this for testing:
echo test | Protect-CmsMessage -to CN=MyCertName | openssl cms -decrypt -inform PEM -inkey key.pem

顺便说一句,CmsMessage 命令将在 PowerShell Core 7.1 上可用,所以你也可以在 Linux/Mac 上使用它(现在处于预览状态,稳定版本将于 2020 年 12 月发布)。

Yet another approach is using Cryptographic Message Syntax (CMS). It's not a pure Node.js solution, but you likely have all tools you need in the box. Below is the example using OpenSSL:

Generate x509 certificate (recipient) and private key files (in Bash):

openssl req  -nodes -new -x509  -keyout key.pem -out cert.pem

Encrypt/Decrypt message from standard input (in Bash):

 echo 123 | openssl cms -encrypt -recip cert.pem | openssl cms -decrypt -inkey key.pem

You can use -in/-out parameters to work with files. Below is an example you can use for Node.js:

require('child_process').execSync("openssl cms -encrypt -in file.json -recip cert.pem -out file.json.cms")

On Linux you'll likely have OpenSSL installed already. You can get OpenSSL on Windows by installing Git Bash, although you can also use built-in PowerShell commands. You'll need to generate a PFX certificate (using New-SelfSignedCertificate) or install existing one (can be generated with OpenSSL too). Once the certificate installed in the certificate store, you can use below commands for encryption/decryption:

Protect-CmsMessage -to CN=MyCertName -Path file.json -OutFile file.json.cms
Unprotect-CmsMessage -Path file.json # It will find proper cert in cert store for you

Below is an example how to generate .pem and PFX certificates from the same private key using OpenSSL, and make messages interchangeable between OpenSSL and PowerShell.

Generate certificate with extensions (that's required on Windows):

openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout key.pem -out cert.pem -subj '/CN=MyCertName' -addext extendedKeyUsage=1.3.6.1.4.1.311.80.1 -addext keyUsage=keyEncipherment

The above snippet will work only for newer versions of OpenSSL (1.1.1). Otherwise you need a separate file to define extensions. Then generate a PFX certificate (protect it with some password):

openssl pkcs12 -export -out certificate.pfx -inkey key.pem -in cert.pem -passout pass:P@ssw0rd

Then copy that PFX file to your Windows machine. You should be able to install it via PowerShell (Import-PfxCertificate) or manually (click on it and follow wizard, use all defaults). In order to make messages interchangeable use the -inform \ -outform parameter when using OpenSSL. For example:

openssl cms -encrypt -in file.json -recip cert.pem -outform PEM 
openssl cms -decrypt -in file.json.cms -inkey key.pem -inform PEM
# If having both OpenSSL/PowerShell on the same OS, use this for testing:
echo test | Protect-CmsMessage -to CN=MyCertName | openssl cms -decrypt -inform PEM -inkey key.pem

Btw, the CmsMessage commands will be available on PowerShell Core 7.1, so you can use it on Linux/Mac too (it's in preview now, and a stable version will be released in Dec 2020).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文