Mimicking the openssl call in node with another library - node.js

I am running this openssl code to generate a token to be used to encrypt my hls stream.
"openssl rand 16 > '" + folder + "/master.key' && echo '" + hex + "' | xxd -r -p > '" + folder + "/master.key'"
The openssl library has issues on windows for I am looking for a way to mimic the above call in a different node library.
I have tried crypto with node js with the call below but it doesn't seem to work.
require('crypto').randomBytes(16, function(err, buffer) {
var hex = buffer.toString('hex');
console.log(hex);
});
Can anyone suggest a way to do this?
Thanks

function hex2bin(hex){
return new Buffer(hex, "hex");
}
require('crypto').randomBytes(16, function(err, buffer) {
var hex = buffer.toString('hex');
fs.writeFile(folder + "/master.key", hex2bin(hex), function (err) {
});
});
Sussed it

Related

Can GraphicsMagick for Node.js process a non-fixed number of images to output a GIF sequence?

I'm using GraphicsMagick for Node.js to generate a GIF sequence from 16 jpg images.
This works very well.
However currently I hardcoded the number of images in the sequence, when I use the function gm().in
I can't find a way or another function to make this number dynamic.
Here is my code:
var tmp_filenames = [];
var nNbStates = 16;
for (var nStateNum=0; nStateNum < nNbStates; nStateNum++)
{
tmp_filenames.push('mypath\myinputfilename' + nStateNum + '.jpg');
}
var gm = require('gm');
gm()
.in(tmp_filenames[0])
.in(tmp_filenames[1])
.in(tmp_filenames[2])
.in(tmp_filenames[3])
.in(tmp_filenames[4])
.in(tmp_filenames[5])
.in(tmp_filenames[6])
.in(tmp_filenames[7])
.in(tmp_filenames[8])
.in(tmp_filenames[9])
.in(tmp_filenames[10])
.in(tmp_filenames[11])
.in(tmp_filenames[12])
.in(tmp_filenames[13])
.in(tmp_filenames[14])
.in(tmp_filenames[15])
.write(output_filename, function (err) {
if (!err) console.log('gif file created!');
});
Thanks for reading.
OK I found a solution.
I was not familiar with this way of using variables and functions
This should work:
var tmp_filenames = [];
var nNbStates = 16;
var bmp = gm();
for (var nStateNum=0; nStateNum < nNbStates; nStateNum++)
{
tmp_filenames.push('mypath\myinputfilename' + nStateNum + '.jpg');
bmp.in(tmp_filenames[nStateNum])
}
.write(output_filename, function (err) {
if (!err) console.log('gif file created!');
});

Create a base64 md5 hash in nodejs equivalent to this openssl command

I have a linux command to create argument value, but I dont know how to convert it in nodejs. This is linux command line:
echo -n '2147483647/s/link127.0.0.1 secret' | \
openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =
and result when execute it in terminal
_e4Nc3iduzkWRm01TBBNYw
Please tell me how to make it in nodejs without child process.
Any terminal command can be executed in Node.js by using the exec or spawn. In this case, exec will probably be your best bet. Follow the pattern below just replace my command to list the directories in /home/username with whatever command you want:
var exec = require('child_process').exec;
exec("ls /home/username", function (error, stdout, stderr) {
console.log("error: ", error);
console.log("stdout: ", stdout);
console.log("stderr: ", stderr);
});
Done
var mysecretkey = "secret";
var path = "/s/link";
var ip = '127.0.0.1';
var time = '2147483647';
var path = time + path + ip + ' ' + mysecretkey;
var crypto = require('crypto');
var md5sum = crypto.createHash('md5');
var d = md5sum.update(path).digest('base64');
//#echo -n '2147483647/s/link127.0.0.1 secret' | openssl md5 -binary | openssl base64 | tr +/ -_ | tr -d =
var test = d.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
console.log(test);

Is 7zip stdout broken? Is there a way to capture the progress in nodejs? [Windows]

I am trying to get the stdout of 7zip when it processes files and get the percentage in nodeJs, but it doesn't behave as expected. 7zip doesn't output anything to stdout until the very end of the execution. Which is not very helpful.. especially when I have large files being compressed and no feedback is shown for a very long time.
The code I am using (simplified):
// 7zip test, place the 7z.exe in the same dir, if it's not on %PATH%
var cp = require('child_process');
var inputFile = process.argv[2]; if(inputFile==null) return;
var regProgress = /(\d{1,3})%\s*$/; //get the last percentage of the string, 3 digits
var proc = cp.spawn("7z.exe",["a","-t7z" ,"-y" ,inputFile + ".7z",inputFile]);
proc.stdout.setEncoding("utf8");
proc.stdout.on("data",function(data){
if(regProgress.test(data))
console.log("Progress = " + regProgress.exec(data)[1] + "%");
});
proc.once("exit",function(exit,sig){ console.log("Complete"); });
I have used the same code to get the percentage with WinRar successfully and I am beginning to think that 7zip might be buggy? Or I am doing it wrong? Can I forcefully read the stdout of a process with a timer perhaps?
The same code above, with the exception of the following line replaced, works as expected with WinRar.
var proc = cp.spawn("Rar.exe",["a","-s","-ma5","-o+",inputFile+".rar",inputFile]);
If anyone knows why this happens and if it is fixable, I would be grateful! :-)
p.s. I have tried 7za.exe, the command line version of 7zip, also the stable, beta and alpha versions, they all have the same issue
It is no longer needed to use a terminal emulator like pty.js, you can pass the -bsp1 to 7z to force to output the progress to stdout.
7-zip only outputs progress when stdout is a terminal.
To trick 7-zip, you need to npm install pty.js (requires Visual Studio or VS Express with Windows SDK) and then use code like:
var pty = require('pty');
var inputFile = process.argv[2],
pathTo7zip = 'c:\\Program Files\\7-Zip\\7z.exe';
if (inputFile == null)
return;
var term = pty.spawn(process.env.ComSpec, [], {
name: 'ansi',
cols: 200,
rows: 30,
cwd: process.env.HOME,
env: process.env
});
var rePrg = /(\d{1,3})%\r\n?/g,
reEsc = /\u001b\[\w{2}/g,
reCwd = new RegExp('^' + process.cwd().replace(/\\/g, '\\\\'), 'm');
prompts = 0,
buffer = '';
term.on('data', function(data) {
var m, idx;
buffer += data;
// remove terminal escape sequences
buffer = buffer.replace(reEsc, '');
// check for multiple progress indicators in the current buffer
while (m = rePrg.exec(buffer)) {
idx = m.index + m[0].length;
console.log(m[1] + ' percent done!');
}
// check for the cmd.exe prompt
if (m = reCwd.exec(buffer)) {
if (++prompts === 2) {
// command is done
return term.kill();
} else {
// first prompt is before we started the actual 7-zip process
if (idx === undefined) {
// we didn't see a progress indicator, so make sure to truncate the
// prompt from our buffer so that we don't accidentally detect the same
// prompt twice
buffer = buffer.substring(m.index + m[0].length);
return;
}
}
}
// truncate the part of our buffer that we're done processing
if (idx !== undefined)
buffer = buffer.substring(idx);
});
term.write('"'
+ pathTo7zip
+ '" a -t7z -y "'
+ inputFile
+ '.7z" "'
+ inputFile
+ '"\r');
It should be noted that 7-zip does not always output 100% at finish. If the file compresses quickly, you may just see only a single 57% for example, so you will have to handle that however you want.

Verify signature on a file nodejs

I don't understand why verify always returns false for me... running openssl will return that everything is just dandy
$ openssl dgst -md5 -verify mykey.pub -signature signature message.txt
Verified OK
However, running my code in the node results in the verification to be false
var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
//pass in arguments
var args = process.argv.slice(2);
fs.readFile(args[0], 'ascii', function(err,signature){
if(err){console.log(err);}
fs.readFile(args[1], 'ascii', function(err,message){
if(err){console.log(err);}
fs.readFile(args[2], 'ascii', function(err,publickey){
if(err){console.log(err);}
verify(signature, message, publickey);
});
});
});
//verify function
var verify = function(signature, message, publickey){
//everything prints out right
console.log(signature.toString() + '\n');
console.log(message.toString() + '\n');
console.log(publickey.toString() + '\n');
//using md5
var verifier = crypto.createVerify('md5');
verifier.update(message.toString());
var WHAT = verifier.verify(publickey.toString(), signature.toString(), 'binary');
console.log(WHAT);
};
Looking at the output results in this
$ node verifyHash signature message.txt mykey.pub
B`⌂ pgfs☼st;3_V1I☻l♂[V5 =C♠~o▲§►rH`KZ7#♦♠LiQ⌂xFw
▼♣"↓d;.H4+↕$WZF▲◄Ow▲r⌂,
j]U↕6►vQm$7v&^^uF↨/ma2F→*n
►¶o'$jN!☼↑☺aV+↔e^qH▲A►rmx.
HEllo
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDgn0PrHxivu0zgG8pp66yMwxJ
MyYsdocVNpZ+673WlRlN0NKQRkI7+F7rYMG4KWL0pDBeOahOggxNVTNV9cxkCKce
Gp37+ZED5HiHKDll4tVoGVSDLaW0BBVe1TzfJSS64fvN/OssyjKffD5ExpLE4O5o
Vv7robQ0JxzYfbz2FQIDAQAB
-----END PUBLIC KEY-----
false
What am I doing wrong?
You cannot read the signature as ASCII, as it contains binary data (byte values > 128). These will get stripped then [1].
As the verifier is a stream.Writable the easiest solution is to use fs.createReadStream and then pipe to pipe it into the verifier.
See this REPL transcript:
> crypto = require('crypto'); undefined
undefined
> fs = require('fs'); undefined
undefined
> verifier = crypto.createVerify('md5'); undefined
undefined
> fs.createReadStream('file').pipe(verifier); undefined
undefined
> verifier.verify(fs.readFileSync('publickey.pem'), fs.readFileSync('signature.sign'), 'binary');
true
[1]
> new Buffer(fs.readFileSync('signature.sign', 'binary')).toString('hex');
'3632c3a6c28dc2806fc2bb563dc3bb51c38b537dc2871ac394c288405dc2b87634c2b5c3be53157273c2bfc3acc2b9c398c2a05e506ec3a6c3b2c2a9c3bf4bc280c28133c298c281c39a07c3acc2a612c2b0c2bec38fc28ac2bbc2b941504fc3bc22c2a0c3910325c38c5f581d4c7f4fc3a3c389c2b4c3b72e36c29b3d29c295c2b4c28755c38158c3af0f0e08c3bbc29f3bc3bc5e57c288c29d287ec3bf1bc39864c2867cc3867bc3a03ec3bd5a2806c3bd55c2a0c29a12c3aac2b675c284500504c38832c291c383c3b933222961c2b3c3bac2a3583737c3861cc392c39373c2bac298c2b96b6c1dc29f3fc2b1c387c397c39719c29fc39ec28c02c29d3cc396c2abc3923bc28e621032c3bec298c2a877c3bbc2ae6fc38cc3b4c2b1c387c390c39d03753bc28ac2b0c2b64f3fc3a7c3a254c398c3b91ec2935922c3aac2bdc2aa41c295c39519c2b8c3bdc2a02d74c2bfc38ec3aa60c2b87c433e1dc28b2351c3b8c2b54a237cc29703521dc3a3c2b34958c2a4c3a9c2a410c2b8c39e5dc3af2c6a27c2987e'
> new Buffer(fs.readFileSync('signature.sign', 'ascii')).toString('hex');
'3632660d006f3b563d7b514b537d071a5408405d387634357e531572733f6c3958205e506e6672297f4b00013318015a076c2612303e4f0a3b3941504f7c22205103254c5f581d4c7f4f634934772e361b3d291534075541586f0f0e087b1f3b7c5e57081d287e7f1b5864067c467b603e7d5a28067d55201a126a367504500504483211437933222961337a23583737461c5253733a18396b6c1d1f3f31475757191f5e0c021d3c562b523b0e6210327e1828777b2e6f4c743147505d03753b0a30364f3f67625458791e1359226a3d2a41155519387d202d743f4e6a60387c433e1d0b235178354a237c1703521d6333495824692410385e5d6f2c6a27187e'
You can also try to use Windows/macOS npm package util sign-check for executables/files signature verification.
It uses built-in OS mechanisms to verify is code signed (codesign --verify command for macOS and WinVerifyTrust API implementation for Windows).
For sign verification you can just use:
const SignCheck = require('sign-check');
const somePath = 'some/path/for/test';
SignCheck.checkMac(somePath).then(
(isSigned) => {
console.log('File sign status ' + isSigned);
},
(error) => {
console.log(error);
}
);
Or checkWin function for Windows platform.

Node.js function to generate RSA keys using Open SSL

I'm using Node.js as a server side language and I would like to generate an RSA key pairs for any user that registers himself on my website. I'm using a module called keypair. It's working fine for keys with small sizes but when I generate keys with 2048 in size, it's taking so long to perform it so I would like to use Open SSL directly from Node.js using Node's child_process as described in the script down below :
var cp = require('child_process')
, assert = require('assert');
var privateKey, publicKey;
publicKey = '';
cp.exec('openssl genrsa 2048', function(err, stdout, stderr) {
assert.ok(!err);
privateKey = stdout;
console.log(privateKey);
makepub = cp.spawn('openssl', ['rsa', '-pubout']);
makepub.on('exit', function(code) {
assert.equal(code, 0);
console.log(publicKey);
});
makepub.stdout.on('data', function(data) {
publicKey += data;
});
makepub.stdout.setEncoding('ascii');
makepub.stdin.write(privateKey);
makepub.stdin.end();
});
This is working and more faster in key pairs generation than the Node.js keypair module so the issue I'm having is that I don't understand this code (if it's writing files on the server side and reading keys from them or not?) and I would like to turn this script into a function that returns a JSON or an array as result that holds the public and private key.
So any suggestion is welcome, thank you in advance.
Try this.. Moved the code around a little. Uses tmp file, which is deleted, possibly could be done without the tmp file, but this should work.
var cp = require('child_process')
, assert = require('assert')
, fs = require('fs')
;
// gen pub priv key pair
function genKeys(cb){
// gen private
cp.exec('openssl genrsa 2048', function(err, priv, stderr) {
// tmp file
var randomfn = './' + Math.random().toString(36).substring(7);
fs.writeFileSync(randomfn, priv);
// gen public
cp.exec('openssl rsa -in '+randomfn+' -pubout', function(err, pub, stderr) {
// delete tmp file
fs.unlinkSync(randomfn);
// callback
cb(JSON.stringify({public: pub, private: priv}, null, 4));
});
});
}
genKeys(console.log);
You can simply use the small rsa-json module
It's really easy to use and it's asynchronous:
var createRsaKeys = require('rsa-json');
createRsaKeys({bits: 1024}, function(err, keyPair) {
console.log(keyPair.private);
console.log(keyPair.public);
});
rsa-json does not make a direct uses of OpenSSL RSA_generate_key but uses ssh-keygen (from OpenSSH) which is a wrapper around OpenSSL. There is no direct security difference (see this for more information).
PS: Have a look at the only 48 lines of code composing rsa-json.
If you really want to use OpenSSL, you can have a look at the ursa module but:
It's not asynchronous
Is not maintained, the last commit was from Dec 21, 2012
The project is heavy, it does too much things like sugary stuff (base64 encoding, etc.).
It's have embedded C++ OpenSSL wrapper inside it, initialized during installation.
PS: keypair uses native JS, that's why it's very slow. It's not recommended with Node.js which is not good at performing CPU-intensive operations (but good with non-blocking events).

Resources