Parse .cer file with nodejs version 12 - node.js

I have a cer file that I want to parse.
To be precise, I used the command in windows: certutil -user My blabla x.cer
this command outputs a cer file.
I want to parse it in order to get its expired date.
I can do it successfully using node16:
const crypto = require('crypto');
const fs = require('fs');
const fileContent = fs.readFileSync('x.cer');
const cert = new crypto.X509Certificate(fileContent);
console.log(cert);
but I cant use it as I need code for node12.
So I tried using node12 with node-forge package:
const fs = require('fs');
const forge = require('node-forge');
const fileContent = fs.readFileSync('x.cer');
const cert = forge.pki.certificateFromPem(fileContent);
console.log(cert);
But it says: Invalid formatted Pem Meessage
How can I parse it correctly?

Related

nodejs PKCS7 decryption and verify with PrivateKey and Cert problem

Im tring to make a nodejs app for decrypt a pem file with some cert.
i made something but couldnt get true verified data.
im getting false and decrypted data wrong.
const crypto = require('crypto');
const forge = require('node-forge');
var privateKeyAssociatedWithCert = fs.readFileSync("./test2.key").toString();
var certOrCertPem = fs.readFileSync("./soft_maya_test_certificate.crt").toString();
let p7d = forge.pkcs7.messageFromPem(decryptedData)
let privateCert = forge.pki.decryptRsaPrivateKey(privateKeyAssociatedWithCert);
p7d.decrypt(p7d.recipients[0], privateCert);
console.log(p7d.content)
var testCert = fs.readFileSync("./test_ca_chain.crt").toString();
var testKey = fs.readFileSync("./test.pem").toString();
var pem = forge.pkcs7.messageToPem(p7d);
console.log(pem)
console.log(Buffer.from(p7d.content.data, 'binary').toString('utf8'))
var v = crypto.createVerify('RSA-SHA256');
v.update(p7d.content.data);
let ffr = v.verify(testCert, testKey, 'binary')
console.log(ffr);

Can NodeJS Crypto Handle Video Files?

I cannot get why the video files cannot be encrypted and then decrypted. When then I try to open the resulting file, it says "This file isn't playable. That might be because the file type is unsupported, the file extension is incorrect, or the file is corrupt.". The same code works perfectly well with audio files. Here is the snippet:
// Nodejs encryption of buffers
const crypto = require('crypto'),
algorithm = 'aes-256-cbc',
password = 'd6F3Efeq';
const fs = require('fs');
let r = fs.createReadStream('video.mp4');
let encrypt = crypto.createCipher(algorithm, password);
let decrypt = crypto.createDecipher(algorithm, password);
let w = fs.createWriteStream('video.out4.mp4');
r.pipe(encrypt).pipe(decrypt).pipe(w);

Can I use the SHA-224 encryption in Dialogflow Node.js?

I am trying to encrypt user input and compare with the encrypted string in database in dialogflow.
How can I add in the crypto package into package.json and get the SHA-224 to work in the index.js?
I have tried my code but nothing happened.
Python code to encrypt data for comparison later:
import hashlib
import pandas as pd
strings = []
data = pd.read_csv("DBDATA.csv")
df = data[['ID']]
for index, row in df.iterrows():
b = row["ID"].encode('utf-8')
print(b)
hashed = hashlib.sha224(b).hexdigest()
strings.append(hashed)
data["NUMBER"] = strings
Javascript code to encrypt user input:
const crypto = require('crypto');
var hash = crypto.createHash('sha224');
var string = agent.parameters.adminnumber;
var hashedString = hash.update(string, 'utf-8');
var gen_hash= hashedString.digest('hex');
Package.json
"dependencies": {
"crypto": "4.0.0"
}
Dialogflow Nodejs
The code work well for me (using a hardcoded "string" var). Maybe you don't see anything because you don't log the result.
Remember install the crypto package using npm install crypto --save command or just npm install if dependency already exists into package.json file.
const crypto = require('crypto');
const hash = crypto.createHash('sha224');
const string = "Test SHA-224 crypto.";
const hashedString = hash.update(string, 'utf-8');
const gen_hash= hashedString.digest('hex');
console.log(gen_hash); // Trace the result
Note: var keyword makes the baby jesuschrist cry

How to use NodeJS crypto to sign a file?

I want to use nodeJS to sign a file. I got one p12 certificate (which includes the private key), a passphrase and a pem certificate.
This here shows how it is been done in ruby:
https://gist.github.com/de4b602a213b4b264706
Thanks in advance!
You should be able to use createSign in the crypto module (see http://nodejs.org/docs/v0.4.2/api/all.html#crypto) to do what you want. The code will end up looking something like this (from http://chimera.labs.oreilly.com/books/1234000001808/ch05.html#chap7_id35952189):
var crypto = require('crypto');
var fs = require('fs');
var pem = fs.readFileSync('key.pem');
var key = pem.toString('ascii');
var sign = crypto.createSign('RSA-SHA256');
sign.update('abcdef'); // data from your file would go here
var sig = sign.sign(key, 'hex');

Encrypting data with a public key in Node.js

I need to encrypt a string using a public key (.pem file), and then sign it using a private key (also a .pem).
I am loading the .pem files fine:
publicCert = fs.readFileSync(publicCertFile).toString();
But after hours of scouring Google, I can't seem to find a way to encrypt data using the public key. In PHP I simply call openssl_public_encrypt(), but I don't see any corresponding function in Node.js or in any modules.
A library is not necessary. Enter crypto.
Here's a janky little module you could use to encrypt/decrypt strings with RSA keys:
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
}
I would recommend not using synchronous fs methods where possible, and you could use promises to make this better, but for simple use cases this is the approach that I have seen work and would take.
I tested this in Node.js 10, you can use encrypt/decrypt functions (small changes on Jacob's answer):
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)
For the keys you can generate them with
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)
}
The updated public/private decrypt and encryption module is URSA. The node-rsa module is outdated.
This Node module provides a fairly complete set of wrappers for the
RSA public/private key crypto functionality of OpenSSL.
npm install ursa
Use the node-rsa module. Here's a link to the test.js file that demonstrates usage.
TL;DR: URSA is your best bet. It's really funky that this doesn't come standard with Node.js' crypto.
Every other solutions I found either doesn't work in Windows or aren't actually encryption libraries. URSA, recommended by Louie, looks like the best bet. If you don't care about Windows, you're even more golden.
Note on Ursa: I had to install OpenSSL along with something called "Visual C++ 2008 Redistributables" in order to get the npm install to work. Get that junk here: http://slproweb.com/products/Win32OpenSSL.html
The breakdown:
Annoying additional manual installation steps for Windows
https://github.com/Obvious/ursa - probably the best of the lot
Not compatible with Windows
https://npmjs.org/package/rsautl - says BADPLATFORM
https://github.com/katyo/node-rsa - node-waf isn't available on Windows
https://github.com/paspao/simple_rsa_encrypt - unistd.h isn't on windows
https://npmjs.org/package/pripub - large amounts of linker errors, also not on GitHub
Not encryption libraries
https://github.com/substack/secure-peer
https://github.com/substack/rsa-json - just generates keys, but doesn't use them
https://github.com/substack/rsa-unpack - just unpacks PEM strings
This is literally all I could find.
This is not supported natively by Node.js version v0.11.13 or below, but it seems that next version of Node.js (a.k.a v0.12) will support this.
Here is the clue: https://github.com/joyent/node/blob/v0.12/lib/crypto.js#L358
See crypto.publicEncrypt and crypto.privateDecrypt
Here is the future documentation for this
https://github.com/joyent/node/blob/7c0419730b237dbfa0ec4e6fb33a99ff01825a8f/doc/api/crypto.markdown#cryptopublicencryptpublic_key-buffer

Resources