web-dev-qa-db-fra.com

Chiffrement des données avec la clé publique dans node.js

J'ai besoin de crypter une chaîne à l'aide d'une clé publique (fichier pem), puis de la signer à l'aide d'une clé privée (également un pem).

Je charge très bien les fichiers pem:

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

mais après des heures passées à parcourir Google, je n'arrive pas à trouver un moyen de crypter les données à l'aide de la clé publique. En php, j'appelle simplement openssl_public_encrypt, mais je ne vois aucune fonction correspondante dans le nœud ou dans les modules.

Si quelqu'un a des suggestions, faites-le moi savoir.

36
Clint

Pas de bibliothèque nécessaire d'amis,

Entrez crypto

Voici un petit module janky que vous pouvez utiliser pour crypter/décrypter des chaînes avec des clés 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
}

Je recommanderais de ne pas utiliser de méthodes fs synchrones dans la mesure du possible, et vous pouvez utiliser Promises pour améliorer cela, mais pour les cas d'utilisation simples, c'est l'approche que j'ai vue fonctionner et que je prendrais

110
Jacob McKay

Le module de décryptage et de cryptage public/privé mis à jour est URSA. le module node-rsa est obsolète.

Ce module Node fournit un ensemble assez complet d'encapsuleurs pour la fonctionnalité de chiffrement à clé publique/privée RSA d'OpenSSL.

npm install ursa

Voir: https://github.com/Obvious/ursa

8
Louie Miranda

J'ai testé cela dans Node 10, vous pouvez utiliser les fonctions de cryptage/décryptage (petits changements sur la réponse de 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)

Pour les clés, vous pouvez les générer avec

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

Que diriez-vous de cela module node-rsa ? Voici un lien vers le fichier test.js qui montre l'utilisation .

7
Peter Lyons

TL; DR: Ursa est votre meilleur choix. C'est vraiment génial que cela ne soit pas standard avec la cryptographie des nœuds.

Toutes les autres solutions que j'ai trouvées ne fonctionnent pas dans Windows ou ne sont pas réellement des bibliothèques de chiffrement. Ursa, recommandée par Louie, ressemble au meilleur pari. Si vous ne vous souciez pas des fenêtres, vous êtes encore plus doré. Remarque sur Ursa, j'ai dû installer Open SSL avec quelque chose appelé "Visual C++ 2008 Redistributables" afin de faire fonctionner l'installation npm. Obtenez cette ordure ici: http://slproweb.com/products/Win32OpenSSL.html

La ventilation:

C'est littéralement tout ce que j'ai pu trouver.

5
B T

Ceci n'est pas pris en charge nativement par la version de nœud v0.11.13 ou inférieure, mais il semble que la prochaine version de nœud (a.k.a v0.12) le supportera.

Voici l'indice: https://github.com/joyent/node/blob/v0.12/lib/crypto.js#L358

voir crypto.publicEncrypt et crypto.privateDecrypt

Voici la future documentation pour cela https://github.com/joyent/node/blob/7c0419730b237dbfa0ec4e6fb33a99ff01825a8f/doc/api/crypto.markdown#cryptopublicencryptpublic_key-buffer

3
Etienne