68

我必须生成两个密钥(私有和公共)以公开加密文本,并让使用私有密钥的用户解密文本。

模块 Crypto 可以吗?

4

9 回答 9

69

nodejs v10.12 现在通过 crypto.generateKeyPair 原生支持这 一点

const { generateKeyPair } = require('crypto');
generateKeyPair('rsa', {
  modulusLength: 4096,
  publicKeyEncoding: {
    type: 'spki',
    format: 'pem'
  },
  privateKeyEncoding: {
    type: 'pkcs8',
    format: 'pem',
    cipher: 'aes-256-cbc',
    passphrase: 'top secret'
  }
}, (err, publicKey, privateKey) => {
  // Handle errors and use the generated key pair.
});
于 2018-10-12T08:41:07.297 回答
25

使用 npm 中的加密模块生成密钥对。

var crypto = require('crypto');

var prime_length = 60;
var diffHell = crypto.createDiffieHellman(prime_length);

diffHell.generateKeys('base64');
console.log("Public Key : " ,diffHell.getPublicKey('base64'));
console.log("Private Key : " ,diffHell.getPrivateKey('base64'));

console.log("Public Key : " ,diffHell.getPublicKey('hex'));
console.log("Private Key : " ,diffHell.getPrivateKey('hex'));

上面是一个示例片段。要了解更多结帐文档http://nodejs.org/api/crypto.html

于 2014-01-02T05:59:14.850 回答
17

以下代码有效,但我不是专业的密码学家,所以这里的一些评论会很有用。

我使用了 ursa RSA 模块,而不是加密。

我担心如果类似的数据是直接加密的,没有通过 AES 或类似的通道,那么破解它可能是微不足道的。请评论...

var ursa = require('ursa');
var fs = require('fs');

// create a pair of keys (a private key contains both keys...)
var keys = ursa.generatePrivateKey();
console.log('keys:', keys);

// reconstitute the private key from a base64 encoding
var privPem = keys.toPrivatePem('base64');
console.log('privPem:', privPem);

var priv = ursa.createPrivateKey(privPem, '', 'base64');

// make a public key, to be used for encryption
var pubPem = keys.toPublicPem('base64');
console.log('pubPem:', pubPem);

var pub = ursa.createPublicKey(pubPem, 'base64');

// encrypt, with the public key, then decrypt with the private
var data = new Buffer('hello world');
console.log('data:', data);

var enc = pub.encrypt(data);
console.log('enc:', enc);

var unenc = priv.decrypt(enc);
console.log('unenc:', unenc);

经过一些进一步的调查http://en.wikipedia.org/w/index.php?title=RSA_%28cryptosystem%29§ion=12#Attacks_against_plain_RSA看起来 ursa 已经做了填充。

于 2014-01-21T15:26:05.830 回答
12

如果你知道如何从 OpenSSL 中得到你想要的,我认为使用 Node 的child_process.

var cp = require('child_process')
  , assert = require('assert')
  ;

var privateKey, publicKey;
publicKey = '';
cp.exec('openssl genrsa 2048', function(err, stdout, stderr) {
  assert.ok(!err);
  privateKey = stdout;
  console.log(privateKey);
  makepub = cp.spawn('openssl', ['rsa', '-pubout']);
  makepub.on('exit', function(code) {
    assert.equal(code, 0); 
    console.log(publicKey);
  });
  makepub.stdout.on('data', function(data) {
    publicKey += data;
  });
  makepub.stdout.setEncoding('ascii');
  makepub.stdin.write(privateKey);
  makepub.stdin.end();  
});
于 2012-01-12T17:08:53.443 回答
11
const crypto = require('crypto');

  const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
      type: 'spki',
      format: 'pem'
    },
    privateKeyEncoding: {
      type: 'pkcs8',
      format: 'pem'
    }
  }); 
于 2019-11-18T20:03:42.127 回答
5

我不知道这是否有帮助,但我也想按照这些思路做点什么。这是我想出的:

正如 Nelson Owalo 的回答中提到的,您可以使用加密库,如下所示:

//import the methods
const { generateKeyPair, createSign, createVerify } = require("crypto");
//generate the key pair
generateKeyPair(
  "rsa",
  {
    modulusLength: 2048, // It holds a number. It is the key size in bits and is applicable for RSA, and DSA algorithm only.
    publicKeyEncoding: {
      type: "pkcs1", //Note the type is pkcs1 not spki
      format: "pem",
    },
    privateKeyEncoding: {
      type: "pkcs1", //Note again the type is set to pkcs1
      format: "pem",
      //cipher: "aes-256-cbc", //Optional
      //passphrase: "", //Optional
    },
  },
  (err, publicKey, privateKey) => {
    // Handle errors and use the generated key pair.
    if (err) console.log("Error!", err);
    console.log({
      publicKey,
      privateKey,
    });//Print the keys to the console or save them to a file.
    /*
    * At this point you will have to pem files, 
    * the public key which will start with 
    * '-----BEGIN RSA PUBLIC KEY-----\n' +
    * and the private key which will start with
    * '-----BEGIN RSA PRIVATE KEY-----\n' +
    */
    //Verify it works by signing some data and verifying it.
    //Create some sample data that we want to sign
    const verifiableData = "this need to be verified";

    // The signature method takes the data we want to sign, the
    // hashing algorithm, and the padding scheme, and generates
    // a signature in the form of bytes
    const signature = require("crypto").sign("sha256", Buffer.from(verifiableData), 
    {
      key: privateKey,
      padding: require("crypto").constants.RSA_PKCS1_PSS_PADDING,
    });
    //Convert the signature to base64 for storage.
    console.log(signature.toString("base64"));

    // To verify the data, we provide the same hashing algorithm and
    // padding scheme we provided to generate the signature, along
    // with the signature itself, the data that we want to
    // verify against the signature, and the public key
    const isVerified = require("crypto").verify(
      "sha256",
      Buffer.from(verifiableData),
      {
        key: publicKey,
        padding: require("crypto").constants.RSA_PKCS1_PSS_PADDING,
      },
      Buffer.from(signature.toString("base64"), "base64")
    );

    // isVerified should be `true` if the signature is valid
    console.log("signature verified: ", isVerified);
  }
);

我认为关键点是使用哪种算法,因为旧版本的 pem 使用 pkcs1 而不是 pkcs8。密钥的开头有助于识别密钥的版本,还包括有关是否加密的信息。希望这可以帮助!

于 2020-10-13T17:29:33.460 回答
0

child_process 路由是 imo 一个糟糕且不可扩展的解决方案。远离。

我选择使用密钥对

于 2014-01-02T05:31:18.260 回答
0

你可以使用这个 rsa-json 模块。它只是产生一个 openssl 进程,因此它非常依赖于操作系统(默认情况下它在 Windows 上不起作用)。

于 2013-01-31T20:12:32.517 回答
0

我没有使用它,但这可能很有用:

http://ox.no/posts/diffie-hellman-support-in-node-js

这方面的文档严重缺乏(没有我能找到的例子)。

于 2011-12-15T17:21:56.963 回答