web-dev-qa-db-ja.com

node.jsの公開キーでデータを暗号化する

公開鍵(pemファイル)を使用して文字列を暗号化し、秘密鍵(pem)を使用して署名する必要があります。

私はpemファイルをうまく読み込んでいます:

publicCert = fs.readFileSync(publicCertFile).toString();

しかし、Googleを数時間精査した後、公開キーを使用してデータを暗号化する方法を見つけることができないようです。 phpでは、単にopenssl_public_encryptを呼び出しますが、ノードまたはモジュールに対応する関数が表示されません。

誰か提案があれば、教えてください。

36
Clint

図書館に必要な友人はいません、

入力 crypto

RSAキーを使用して文字列を暗号化/復号化するために使用できるジャンキーな小さなモジュールを次に示します。

var crypto = require("crypto");
var path = require("path");
var fs = require("fs");

var encryptStringWithRsaPublicKey = function(toEncrypt, relativeOrAbsolutePathToPublicKey) {
    var absolutePath = path.resolve(relativeOrAbsolutePathToPublicKey);
    var publicKey = fs.readFileSync(absolutePath, "utf8");
    var buffer = Buffer.from(toEncrypt);
    var encrypted = crypto.publicEncrypt(publicKey, buffer);
    return encrypted.toString("base64");
};

var decryptStringWithRsaPrivateKey = function(toDecrypt, relativeOrAbsolutePathtoPrivateKey) {
    var absolutePath = path.resolve(relativeOrAbsolutePathtoPrivateKey);
    var privateKey = fs.readFileSync(absolutePath, "utf8");
    var buffer = Buffer.from(toDecrypt, "base64");
    var decrypted = crypto.privateDecrypt(privateKey, buffer);
    return decrypted.toString("utf8");
};

module.exports = {
    encryptStringWithRsaPublicKey: encryptStringWithRsaPublicKey,
    decryptStringWithRsaPrivateKey: decryptStringWithRsaPrivateKey
}

可能な場合は同期fsメソッドを使用しないことをお勧めします。Promisesを使用してこれを改善することもできますが、単純なユースケースの場合、これは私が取り組んでいるアプローチです。

110
Jacob McKay

更新されたパブリック/プライベート復号化および暗号化モジュールはURSAです。 node-rsaモジュールは時代遅れです。

このNodeモジュールは、OpenSSLのRSA公開/秘密キー暗号化機能のラッパーのかなり完全なセットを提供します。

npm install ursa

参照: https://github.com/Obvious/ursa

8
Louie Miranda

これをNode 10でテストしました。暗号化/復号化関数を使用できます(Jacobの答えに対する小さな変更)

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

function encrypt(toEncrypt, relativeOrAbsolutePathToPublicKey) {
  const absolutePath = path.resolve(relativeOrAbsolutePathToPublicKey)
  const publicKey = fs.readFileSync(absolutePath, 'utf8')
  const buffer = Buffer.from(toEncrypt, 'utf8')
  const encrypted = crypto.publicEncrypt(publicKey, buffer)
  return encrypted.toString('base64')
}

function decrypt(toDecrypt, relativeOrAbsolutePathtoPrivateKey) {
  const absolutePath = path.resolve(relativeOrAbsolutePathtoPrivateKey)
  const privateKey = fs.readFileSync(absolutePath, 'utf8')
  const buffer = Buffer.from(toDecrypt, 'base64')
  const decrypted = crypto.privateDecrypt(
    {
      key: privateKey.toString(),
      passphrase: '',
    },
    buffer,
  )
  return decrypted.toString('utf8')
}

const enc = encrypt('hello', `public.pem`)
console.log('enc', enc)

const dec = decrypt(enc, `private.pem`)
console.log('dec', dec)

キーについては、次を使用して生成できます

const { writeFileSync } = require('fs')
const { generateKeyPairSync } = require('crypto')

function generateKeys() {
  const { privateKey, publicKey } = generateKeyPairSync('rsa', {
    modulusLength: 4096,
    publicKeyEncoding: {
      type: 'pkcs1',
      format: 'pem',
    },
    privateKeyEncoding: {
      type: 'pkcs1',
      format: 'pem',
      cipher: 'aes-256-cbc',
      passphrase: '',
    },
  })

  writeFileSync('private.pem', privateKey)
  writeFileSync('public.pem', publicKey)
}
7
BrunoLM

これはどうですか node-rsa module使用法を示すtest.jsファイル へのリンクです。

7
Peter Lyons

TL; DR:Ursaが最善の策です。これは、ノード暗号化には標準ではないというのが本当にファンキーです。

私が見つけた他のすべてのソリューションは、Windowsで機能しないか、実際には暗号化ライブラリではありません。 Louieが推奨するUrsaは、最善策のようです。あなたが窓を気にしないなら、あなたはさらに金色です。 Ursaについては、npmインストールを機能させるために、「Visual C++ 2008 Redistributables」と呼ばれるものとともにOpen SSLをインストールする必要がありました。ここでそのジャンクを取得します: http://slproweb.com/products/Win32OpenSSL.html

内訳:

これは文字通り私が見つけることができるすべてです。

5
B T

これは、ノードバージョンv0.11.13以前ではネイティブにサポートされていませんが、ノードの次のバージョン(a.k.a v0.12)でサポートされるようです。

ここに手がかりがあります: https://github.com/joyent/node/blob/v0.12/lib/crypto.js#L358

見る crypto.publicEncryptおよびcrypto.privateDecrypt

これの今後のドキュメントはこちらです https://github.com/joyent/node/blob/7c0419730b237dbfa0ec4e6fb33a99ff01825a8f/doc/api/crypto.markdown#cryptopublicencryptpublic_key-buffer

3
Etienne