De la documentation NodeJS sur TLS/SSL pour Node v10.9.0 (2018-AUG))
https://nodejs.org/api/tls.html#tls_tls_ssl_concepts
openssl genrsa -out ryans-key.pem 2048
Produira:
-----BEGIN RSA PRIVATE KEY-----
base64 encoded magic here...
-----END RSA PRIVATE KEY-----
Que je peux ensuite utiliser avec succès la classe Sign
pour signer cryptographiquement un message:
https://nodejs.org/api/crypto.html#crypto_class_sign
const crypto = require('crypto');
const sign = crypto.createSign('RSA-SHA256');
sign.update('some data to sign');
const privateKey = `Insert magic value from above`;
console.log(sign.sign(privateKey, 'base64'));
J'ai essayé ce qui suit sans succès:
const crypto = require('crypto');
const dhke = crypto.createDiffieHellman(2048);
dhke.generateKeys();
const private_pem = `-----BEGIN RSA PRIVATE KEY-----
${dhke.getPrivateKey('base64')}
-----END RSA PRIVATE KEY-----`;
console.log(private_pem);
const sign = crypto.createSign('RSA-SHA256');
sign.update('some data to sign');
const signature = sign.sign(private_pem, 'base64');
console.log(signature);
Obtention de l'erreur suivante:
Error: error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long
at Sign.sign (internal/crypto/sig.js:84:26)
...
Comment utiliser la bibliothèque crypto
dans NodeJS pour réaliser ce que l'outil de ligne de commande openssl
effectue (ou un autre module NPM) pour créer une paire de clés publique/privée au format PEM valide qui est requise par la classe Sign
?
Voici la solution de travail du début à la fin grâce à la réponse acceptée de JacobTDC où NodeJS v10.12.0 a ajouté cette fonctionnalité.
const crypto = require('crypto'); const sign = crypto.createSign('RSA-SHA256');
sign.update('some data to sign');
// $ openssl genrsa -out ryans-key.pem 2048
// const privateKey = `Insert magic value from above`;
const { generateKeyPairSync } = require('crypto');
const { publicKey, privateKey } = generateKeyPairSync('rsa',
{ modulusLength: 2048, // the length of your key in bits
publicKeyEncoding: {
type: 'spki', // recommended to be 'spki' by the Node.js docs
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8', // recommended to be 'pkcs8' by the Node.js docs
format: 'pem',
//cipher: 'aes-256-cbc', // *optional*
//passphrase: 'top secret' // *optional*
}
});
console.log(privateKey);
console.log(sign.sign(privateKey, 'base64'));
Depuis Node.js v10.12.0, vous pouvez utiliser crypto.generateKeyPair et crypto.generateKeyPairSync .
J'ai fourni un exemple à partir des documents Node.js ci-dessous (avec des commentaires ajoutés):
const { generateKeyPairSync } = require('crypto');
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
modulusLength: 4096, // the length of your key in bits
publicKeyEncoding: {
type: 'spki', // recommended to be 'spki' by the Node.js docs
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8', // recommended to be 'pkcs8' by the Node.js docs
format: 'pem',
cipher: 'aes-256-cbc', // *optional*
passphrase: 'top secret' // *optional*
}
});
Le problème ici est que les clés DH ne sont pas des clés RSA et ne sont pas entièrement compatibles.
Malheureusement, node n'a pas non plus la capacité de produire de vraies paires RSA via le module crypto
ce qui est un peu décevant. Pour ce faire, vous devrez soit interagir avec votre bibliothèque locale openssl
, soit avec un module tiers en fonction de vos besoins.
En ce qui concerne les modules tiers, keypair
est une bibliothèque simple qui fonctionnera dans votre situation donnée
const keypair = require('keypair');
const keys: { private: string, public: string } = keypair({ bits : 2056 }); // 2056 is the default but added for example
J'ai également trouvé de bons résultats avec openpgpjs
qui est beaucoup plus en vedette tout en se concentrant sur le fait d'être un module indépendant de la plate-forme. Si vous cherchez à faire de la cryptographie dans le navigateur ainsi que dans le nœud, cela pourrait être une bonne option.