微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 NodeJS 生成持久化和加载密钥?

如何解决如何使用 NodeJS 生成持久化和加载密钥?

我一直在学习 NodeJS 和加密库。具体来说,我想生成一个签名然后验证它。我有下面的工作代码。 NodeJS Crypto 库文档足以解决这个问题。我还可以将这些密钥导出为 PEM,因此我可以使用 fs.writeFile 将其保存到磁盘。但是我遇到了一个寻找文档和/或如何再次加载 PEM 密钥的示例的墙。我将如何保存密钥以便我可以在以后加载它们以验证签名?是否有内置方法,或者我应该只保存 PEM,然后再加载它。加载 PEM 后,我将如何使用加密库将 PEM 字符串转换回实际的 crypto.KeyObject?

const crypto = require('crypto');

(async () => {
    const { publicKey,privateKey } = crypto.generateKeyPairsync("rsa",{
        //The standard secure default length for RSA keys is 2048 bits
        modulusLength: 2048,});

    let data = "Signing Data";

    const signature = crypto.sign("sha256",Buffer.from(data),{
        key: privateKey,padding: crypto.constants.RSA_PKCS1_PSS_PADDING,});

    console.log(signature.toString("base64"))

    const isverified = crypto.verify(
        "sha256",{
            key: publicKey,},signature
    )

    console.log("signature verified: ",isverified);
})();

解决方法

如您所说,您可以使用 writeFile 保存您的密钥,然后您可以使用 readFile 取回它们。

此外,您应该使用 require("fs/promises") 而不是 require("fs"),因为您使用的是异步自动调用函数。

const fs = require("fs/promises")

const KEY_FILE_PATH = `${__dirname}/MY_KEY`

(async () => {
  const privateKey = "..."
  
  await fs.writeFile(KEY_FILE_PATH,privateKey)

  // Later

  const key = await fs.readFile(KEY_FILE_PATH)

})()
,

很抱歉我懒得更改您的代码,但我有一个示例代码正在执行请求的行为。

它从 PEM 文件中加载私有和公共 RSA 密钥,使用 PSS 填充和 32 字节长的盐对数据进行签名和验证。

您可以在实时编译器中运行示例代码:https://repl.it/@javacrypto/SoNodeJsCryptoRsaPssSignatureString#index.js

这是输出(由于随机填充,您的输出会有所不同):

RSA PSS signature string
dataToSign:   The quick brown fox jumps over the lazy dog

* * * sign the plaintext with the RSA private key * * *
used private key:
 <Buffer 2d 2d 2d 2d 2d 42 45 47 49 4e 20 50 52 49 56 41 54 45 20 4b 45 59 2d 2d 2d 2d 2d 0d 0a 4d 49 49 45 76 67 49 42 41 44 41 4e 42 67 6b 71 68 6b 69 47 39 ... 1682 more bytes>
signature (Base64):  vCSB4744p30IBl/sCLjvKm2nix7wfScQn99YX9tVIDNQIvU3QnSCLc2cF+J6R9WMRIXOsY94MxjKCQANW0CuaSs+w31ePHaounFVnmXyY092SicZrtpwlxw2CHqJ0NSyciDpxlRId1vjKlp9E5IJmYtVMtL2hfb711P+nb+m+1sPplNXPpJpdnWIzfLsDMVxCkplAdrcoH2HuWgOtOCHAf3vWbUC/vkvi388NT1UXJRPoERM0m1v11ogP9DiycMdoJxg3fbdH3HknbR02MLNEr7q4ZMzlrKxnYChwp2hnnBvJDcXpPDnQz7sG8zrim1nL/PS8CRG5lxhYYAZqTc+Vg==

* * * verify the signature against the plaintext with the RSA public key * * *
used public_key:
 <Buffer 2d 2d 2d 2d 2d 42 45 47 49 4e 20 50 55 42 4c 49 43 20 4b 45 59 2d 2d 2d 2d 2d 0d 0a 4d 49 49 42 49 6a 41 4e 42 67 6b 71 68 6b 69 47 39 77 30 42 41 51 ... 410 more bytes>

signature (Base64) verified:  true

这是我的完整示例代码,请记住没有异常处理,代码仅用于教育目的

const crypto = require('crypto');
const fs = require('fs');

console.log('RSA PSS signature string');
const dataToSign = 'The quick brown fox jumps over the lazy dog';
console.log('dataToSign:  ',dataToSign);

var filenamePrivateKeyPem = "privatekey2048.pem";
var filenamePublicKeyPem = "publickey2048.pem";

console.log('\n* * * sign the plaintext with the RSA private key * * *');

const private_key = fs.readFileSync(filenamePrivateKeyPem);
console.log('used private key:\n',private_key);
const signatureBase64 = rsaSignToBase64(private_key,dataToSign);
console.log('signature (Base64): ',signatureBase64);

console.log('\n* * * verify the signature against the plaintext with the RSA public key * * *');

const public_key = fs.readFileSync(filenamePublicKeyPem);
console.log('used public_key:\n',public_key);
const signatureVerified = rsaVerifySignatureFromBase64(public_key,dataToSign,signatureBase64);
console.log('\nsignature (Base64) verified: ',signatureVerified)

function rsaSignToBase64(privateKey,message) {
  const signer = crypto.createSign('sha256');
  signer.update(message);
  signer.end();
  const signature = signer.sign(private_key)
  return signature.toString('Base64')
}

function rsaVerifySignatureFromBase64(publicKey,message,signatureBase64) {
  const signature = base64Decoding(signatureBase64);
  const verifier = crypto.createVerify('sha256');
  verifier.update(message);
  verifier.end();
  return verifier.verify(public_key,signature);
}

function base64Decoding(input) {
  return Buffer.from(input,'base64')
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。