Reputation:
I have to write a code in Node js using crypto module (as I am not allowed to use any module apart from MIT licensed). I need to generate a key pair and encrypt some message with the pulic key and decrypt it with private key. The first part i.e generation of key pair is done. I am not getting any clue how to use crypto modue to encrypt and decrypt some message using the same key pair.
Upvotes: 2
Views: 8063
Reputation: 1464
This solution:
All the data is converted to base64 strings to make it easy to pass these values around on the web.
It is what I was looking for when digesting this process.
'use strict';
import crypto from 'crypto';
import fs from 'fs';
// Make public/private RSA key pair
let keyPair = await crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-512",
},
true,
["encrypt", "decrypt"]
);
// export public key as base64 string and save to file
const exportedPublicKey = await crypto.subtle.exportKey('spki', keyPair.publicKey);
const expPublicKeyBase64 = Buffer.from(exportedPublicKey).toString('base64');
fs.writeFileSync('./publickey.txt', expPublicKeyBase64);
// export private key as base64 string and save to file
const exportedPrivateKey = await crypto.subtle.exportKey('pkcs8', keyPair.privateKey);
const exportedPrivateKeyBase64 = Buffer.from(exportedPrivateKey).toString('base64');
fs.writeFileSync('./privatekey.txt', exportedPrivateKeyBase64);
// import and make public key from base64 file
const publicKeyBase64Buffer = fs.readFileSync('./publickey.txt');
const publicKeyBase64String = Buffer.from(publicKeyBase64Buffer).toString('ascii');
const publicKeyBuffer = Buffer.from(publicKeyBase64String, 'base64');
const publicCryptoKey = await crypto.subtle.importKey(
'spki',
publicKeyBuffer,
{ name: 'RSA-OAEP', hash: "SHA-512" },
false,
["encrypt"]
);
// encrypt some plaintext using public key, convert to base64, and save to file
const plainText = 'abc';
const plainTextUInt8 = (new TextEncoder()).encode(plainText);
const cypherTextBuffer = await crypto.subtle.encrypt(
{ name: "RSA-OAEP", hash: "SHA-512" },
publicCryptoKey,
plainTextUInt8
);
const cypherTextBase64 = Buffer.from(cypherTextBuffer).toString('base64');
fs.writeFileSync('./cypherText.txt', cypherTextBase64);
// import and make private key from base64 file
const privateKeyBase64Buffer = fs.readFileSync('./privatekey.txt');
const privateKeyBase64String = Buffer.from(privateKeyBase64Buffer).toString('ascii');
const privateKeyBuffer = Buffer.from(privateKeyBase64String, 'base64');
const privateCryptoKey = await crypto.subtle.importKey(
'pkcs8',
privateKeyBuffer,
{ name: 'RSA-OAEP', hash: "SHA-512" },
false,
["decrypt"]
);
// open base64 encrypted file and decrypt using private key
const cypherTxtBase64Buffer = fs.readFileSync('./cypherText.txt');
const cypherTxtBase64String = Buffer.from(cypherTxtBase64Buffer).toString('ascii');
const cypherTxtBuffer = Buffer.from(cypherTxtBase64String, 'base64');
const plainTxtBuff = await crypto.subtle.decrypt('RSA-OAEP', privateCryptoKey, cypherTxtBuffer);
const plainTxt = Buffer.from(plainTxtBuff).toString('ascii');
console.log(plainTxt);
Upvotes: 0
Reputation: 91
This should do what you want:
const { generateKeyPairSync, publicEncrypt, privateDecrypt } = require('crypto');
//generate a key pair RSA type encryption with a .pem format
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
modulusLength: 4096,
publicKeyEncoding: {
type: 'spki',
format: 'pem'
},
privateKeyEncoding: {
type: 'pkcs8',
format: 'pem',
}
});
// print out the generated keys
console.log(`PublicKey: ${publicKey}`);
console.log(`PrivateKey: ${privateKey}`);
//message to be encrypted
var toEncrypt = "my secret text to be encrypted";
var encryptBuffer = Buffer.from(toEncrypt);
//encrypt using public key
var encrypted = publicEncrypt(publicKey,encryptBuffer);
//print out the text and cyphertext
console.log("Text to be encrypted:");
console.log(toEncrypt);
console.log("cipherText:");
console.log(encrypted.toString());
//decrypt the cyphertext using the private key
var decryptBuffer = Buffer.from(encrypted.toString("base64"), "base64");
var decrypted = privateDecrypt(privateKey,decryptBuffer);
//print out the decrypted text
console.log("decripted Text:");
console.log(decrypted.toString());
It generates a key pair that can be used to encrypt and decrypt a message.
Upvotes: 9
Reputation: 823
In the Node Documentation for the Crypto lib is the following example:
var crypto = require('crypto');
var alice = crypto.getDiffieHellman('modp5');
var bob = crypto.getDiffieHellman('modp5');
alice.generateKeys();
bob.generateKeys();
var alice_secret = alice.computeSecret(bob.getPublicKey(), null, 'hex');
var bob_secret = bob.computeSecret(alice.getPublicKey(), null, 'hex');
/* alice_secret and bob_secret should be the same */
console.log(alice_secret == bob_secret);
This example shows how to compute a shared secret
which can then be used with .createCipher()
and .createDecipher()
as shown below:
var encrypt64 = function(aMsg, aSecret) {
var cipher, tRet;
cipher = crypto.createCipher('aes-256-cbc', aSecret);
tRet = cipher.update(aMsg, 'utf8', 'base64');
tRet += cipher.final('base64');
return tRet;
};
var decrypt64 = function(aMsg, aSecret) {
var decipher, tRet;
decipher = crypto.createDecipher('aes-256-cbc', aSecret);
tRet = decipher.update(aMsg.replace(/\s/g, "+"), 'base64', 'utf8');
tRet += decipher.final('utf8');
return tRet;
};
Upvotes: 0