Right way to cipher / uncipher message with Node.JS? - javascript

I use this to Cipher a message:
const CIPHER_ALGORITHM = 'aes256';
var cipherMessage = function(data, key) {
try {
var cipher = crypto.createCipher(CIPHER_ALGORITHM, key);
var cipheredData = cipher.update(data, "binary", "hex");
cipheredData += cipher.final("hex");
return cipheredData;
} catch(e) {
return null;
}
}
And this to uncipher a message:
var decipherMessage = function(msg, key) {
var ret = {};
try {
var decipher = crypto.createDecipher(CIPHER_ALGORITHM, key);
var decipheredMessage = decipher.update(msg, 'hex', 'binary');
decipheredMessage += decipher.final("binary");
ret = JSON.parse(decipheredMessage);
} catch(e) {
return null;
}
return ret;
}
I have to call them multiple time (every second), it it the right way to do it ?
Is there any possibility of memory leak with that ?

Related

Read files from directory and save to array of object

I have a directory of the tax file of employees. Each file has a filename as employee code. I am reading each file and extract some components and save to an array of employee objects.
const readline = require('readline');
let empArr = [];
function readFiles(dirname) {
fs.readdir(dirname, async function (err,filenames) {
if(err) {
return err;
}
for await (file of filenames) {
const filePath = path.join(__dirname,directoryPath,file);
const readStream = fs.createReadStream(filePath);
const fileContent = readline.createInterface({
input: readStream
});
let employeeObj = {
empId : '',
TotalEarning:'',
ProfessionalTax:0,
GrossIncome:0,
isDone:false
};
fileContent.on('line', function(line) {
if(!employeeObj.empId && line.includes("Employee:")) {
const empId = line.replace('Employee: ','').split(" ")[0];
employeeObj.empId = empId;
}
else if(line.includes('Total Earnings')) {
const amount = line.replace(/[^0-9.]/g,'');
employeeObj.TotalEarning = amount;
}
else if(line.includes('Profession Tax')) {
const amount = line.split(" ").pop() || 0;
employeeObj.ProfessionalTax = amount;
}
else if(line.includes('Gross Income')) {
const amount = line.replace(/[^0-9.]/g,'');
employeeObj.GrossIncome = amount ||0;
}
else if(line.includes('finance department immediately')) {
employeeObj.isDone =true;
empArr.push(employeeObj);
}
});
fileContent.on('close', function() {
fileContent.close();
});
}
})
}
readFiles(directoryPath);
I am not able to get empArr. After getting the array, I need to save to excel. That part I will try after getting the array of employee objects.
I got it working after reading several articles on closure and promises. The below code works for me and sends me array of employees that are processed.
const directoryPath = './tax/';
function readFiles(dirname) {
fs.readdir(dirname, async function (err,filenames) {
if(err) {
return err;
}
let promiseArr = filenames.map( file=> {
return new Promise((resolve)=>{
processFile(file, resolve)
})
});
Promise.all(promiseArr).then((ret)=>console.log(ret));
})
}
function processFile(file, callback) {
const filePath = path.join(__dirname,directoryPath,file);
const readStream = fs.createReadStream(filePath);
const fileContent = readline.createInterface({
input: readStream
});
let employeeObj = {
empId : '',
TotalEarning:'',
ProfessionalTax:0,
GrossIncome:0,
isDone:false
};
fileContent.on('line', function(line) {
if(!employeeObj.empId && line.includes("Employee:")) {
const empId = line.replace('Employee: ','').split(" ")[0];
employeeObj.empId = empId;
}
else if(line.includes('Total Earnings')) {
const amount = line.replace(/[^0-9.]/g,'');
employeeObj.TotalEarning = amount;
}
else if(line.includes('Profession Tax')) {
const amount = line.split(" ").pop() || 0;
employeeObj.ProfessionalTax = amount;
}
else if(line.includes('Gross Income')) {
const amount = line.replace(/[^0-9.]/g,'');
employeeObj.GrossIncome = amount ||0;
}
else if(line.includes('finance department immediately')) {
employeeObj.isDone = true;
return callback(employeeObj);
}
});
fileContent.on('close', function() {
fileContent.close();
});
}
readFiles(directoryPath);
Surely, the code can be improved further.

Unhandled Rejection (TypeError): Cannot read property '2' of null

I am using google spreadsheet as a CMS for my React app. I have the required credentials from google developer console saved in a dotenv file. But the REACT_APP_PRIVATE_KEY is causing this error.
The App works perfectly when I hardcode the PRIVATE_KEY value in my handleSubmit function .
Please Help(PS if anybody needs any other file please let me know)
dotenv
REACT_APP_PRIVATE_KEY=-----BEGIN PRIVATE KEY-----\n*********\n-----END PRIVATE KEY-----\n
REACT_APP_CLIENT_EMAIL=**********.gserviceaccount.com
REACT_APP_SHEET_ID=*********
handleSubmit function
const handleSubmit=async (e)=>{
const doc =new GoogleSpreadsheet(process.env.REACT_APP_SHEET_ID);
console.log(process.env.REACT_APP_PRIVATE_KEY)
console.log(process.env.REACT_APP_CLIENT_EMAIL)
await doc.useServiceAccountAuth({
client_email:process.env.REACT_APP_CLIENT_EMAIL,
private_key: process.env.REACT_APP_PRIVATE_KEY
});
await doc.loadInfo();
const sheet = doc.sheetsByIndex[0];
await sheet.addRow({Website:website,Password:password})
window.location.reload();
}
Here is the screenshot of the error console: https://imgur.com/a/9OlgQ1X
EDIT-1
parseKeys index.js
var asn1 = require('./asn1')
var aesid = require('./aesid.json')
var fixProc = require('./fixProc')
var ciphers = require('browserify-aes')
var compat = require('pbkdf2')
var Buffer = require('safe-buffer').Buffer
module.exports = parseKeys
function parseKeys (buffer) {
var password
if (typeof buffer === 'object' && !Buffer.isBuffer(buffer)) {
password = buffer.passphrase
buffer = buffer.key
}
if (typeof buffer === 'string') {
buffer = Buffer.from(buffer)
}
var stripped = fixProc(buffer, password) ///<=line 19
var type = stripped.tag
var data = stripped.data
var subtype, ndata
switch (type) {
case 'CERTIFICATE':
ndata = asn1.certificate.decode(data, 'der').tbsCertificate.subjectPublicKeyInfo
// falls through
case 'PUBLIC KEY':
if (!ndata) {
ndata = asn1.PublicKey.decode(data, 'der')
}
subtype = ndata.algorithm.algorithm.join('.')
switch (subtype) {
case '1.2.840.113549.1.1.1':
return asn1.RSAPublicKey.decode(ndata.subjectPublicKey.data, 'der')
case '1.2.840.10045.2.1':
ndata.subjectPrivateKey = ndata.subjectPublicKey
return {
type: 'ec',
data: ndata
}
case '1.2.840.10040.4.1':
ndata.algorithm.params.pub_key = asn1.DSAparam.decode(ndata.subjectPublicKey.data, 'der')
return {
type: 'dsa',
data: ndata.algorithm.params
}
default: throw new Error('unknown key id ' + subtype)
}
// throw new Error('unknown key type ' + type)
case 'ENCRYPTED PRIVATE KEY':
data = asn1.EncryptedPrivateKey.decode(data, 'der')
data = decrypt(data, password)
// falls through
case 'PRIVATE KEY':
ndata = asn1.PrivateKey.decode(data, 'der')
subtype = ndata.algorithm.algorithm.join('.')
switch (subtype) {
case '1.2.840.113549.1.1.1':
return asn1.RSAPrivateKey.decode(ndata.subjectPrivateKey, 'der')
case '1.2.840.10045.2.1':
return {
curve: ndata.algorithm.curve,
privateKey: asn1.ECPrivateKey.decode(ndata.subjectPrivateKey, 'der').privateKey
}
case '1.2.840.10040.4.1':
ndata.algorithm.params.priv_key = asn1.DSAparam.decode(ndata.subjectPrivateKey, 'der')
return {
type: 'dsa',
params: ndata.algorithm.params
}
default: throw new Error('unknown key id ' + subtype)
}
// throw new Error('unknown key type ' + type)
case 'RSA PUBLIC KEY':
return asn1.RSAPublicKey.decode(data, 'der')
case 'RSA PRIVATE KEY':
return asn1.RSAPrivateKey.decode(data, 'der')
case 'DSA PRIVATE KEY':
return {
type: 'dsa',
params: asn1.DSAPrivateKey.decode(data, 'der')
}
case 'EC PRIVATE KEY':
data = asn1.ECPrivateKey.decode(data, 'der')
return {
curve: data.parameters.value,
privateKey: data.privateKey
}
default: throw new Error('unknown key type ' + type)
}
}
parseKeys.signature = asn1.signature
function decrypt (data, password) {
var salt = data.algorithm.decrypt.kde.kdeparams.salt
var iters = parseInt(data.algorithm.decrypt.kde.kdeparams.iters.toString(), 10)
var algo = aesid[data.algorithm.decrypt.cipher.algo.join('.')]
var iv = data.algorithm.decrypt.cipher.iv
var cipherText = data.subjectPrivateKey
var keylen = parseInt(algo.split('-')[1], 10) / 8
var key = compat.pbkdf2Sync(password, salt, iters, keylen, 'sha1')
var cipher = ciphers.createDecipheriv(algo, key, iv)
var out = []
out.push(cipher.update(cipherText))
out.push(cipher.final())
return Buffer.concat(out)
}
EDIT-2
fixproc.js
// adapted from https://github.com/apatil/pemstrip
var findProc = /Proc-Type: 4,ENCRYPTED[\n\r]+DEK-Info: AES-((?:128)|(?:192)|(?:256))-CBC,([0-9A-H]+)[\n\r]+([0-9A-z\n\r+/=]+)[\n\r]+/m
var startRegex = /^-----BEGIN ((?:.*? KEY)|CERTIFICATE)-----/m
var fullRegex = /^-----BEGIN ((?:.*? KEY)|CERTIFICATE)-----([0-9A-z\n\r+/=]+)-----END \1-----$/m
var evp = require('evp_bytestokey')
var ciphers = require('browserify-aes')
var Buffer = require('safe-buffer').Buffer
module.exports = function (okey, password) {
var key = okey.toString()
var match = key.match(findProc)
var decrypted
if (!match) {
var match2 = key.match(fullRegex)
decrypted = Buffer.from(match2[2].replace(/[\r\n]/g, ''), 'base64') //<=line14
} else {
var suite = 'aes' + match[1]
var iv = Buffer.from(match[2], 'hex')
var cipherText = Buffer.from(match[3].replace(/[\r\n]/g, ''), 'base64')
var cipherKey = evp(password, iv.slice(0, 8), parseInt(match[1], 10)).key
var out = []
var cipher = ciphers.createDecipheriv(suite, cipherKey, iv)
out.push(cipher.update(cipherText))
out.push(cipher.final())
decrypted = Buffer.concat(out)
}
var tag = key.match(startRegex)[1]
return {
tag: tag,
data: decrypted
}
}
try to hash your private key into base64 string, then put the hashed value in the env file and when using, decode it. This is the safer way to store private keys

How to handle axios.all request fails

How can I handle request fails in this example of axios.all requests. I.e. if all servers are responde with JSON all is okay and I have JSON file at end of a cycle. But if one of this servers not responde with JSON or not responde at all I do have nothing in "/data.json" file, even all other servers are working perfectly. How can I catch a server fail and skip it?
var fs = require("fs");
var axios = require('axios');
var util = require('util');
var round = 0;
var tmp = {};
var streem = fs.createWriteStream(__dirname + '/data.json', {flags : 'w'});
toFile = function(d) { //
streem.write(util.format(d));
};
start();
setInterval(start, 27000);
function start(){
streem = fs.createWriteStream(__dirname + '/data.json', {flags : 'w'});
monitor();
}
function monitor(){
axios.all([
axios.get('server1:api'),
axios.get('server2:api'),
axios.get('server3:api'),
axios.get('server4:api'),
]).then(axios.spread((response1, response2, response3, response4) => {
tmp.servers = {};
tmp.servers.server1 = {};
tmp.servers.server1 = response1.data;
tmp.servers.server2 = {};
tmp.servers.server2 = response2.data;
tmp.servers.server3 = {};
tmp.servers.server3 = response3.data;
tmp.servers.server4 = {};
tmp.servers.server4 = response4.data;
toFile(JSON.stringify(tmp));
round++;
streem.end();
streem.on('finish', () => {
console.error('Round: ' + round);
});
})).catch(error => {
console.log(error);
});
}
The most standard way to approach this would be a recursive function like below.
let promises = [
axios.get('server1:api'),
axios.get('server2:api'),
axios.get('server3:api'),
axios.get('server4:api'),
];
async function monitor() {
const responses = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments))[0];
const nextPromise = promises.shift();
if (nextPromise) {
try {
const response = await getSentenceFragment(offset);
responses.push(response);
}
catch (error) {
responses.push({});
}
return responses.concat(await monitor(responses));
} else {
return responses;
}
}
monitor([]).then(([response1, response2, response3, response4]) => {
tmp.servers = {};
tmp.servers.server1 = {};
tmp.servers.server1 = response1.data;
tmp.servers.server2 = {};
tmp.servers.server2 = response2.data;
tmp.servers.server3 = {};
tmp.servers.server3 = response3.data;
tmp.servers.server4 = {};
tmp.servers.server4 = response4.data;
toFile(JSON.stringify(tmp));
round++;
streem.end();
streem.on('finish', () => {
console.error('Round: ' + round);
});
});

How to make private varaible in JS

I want to save a private variable(secret) when require a file/module. The secret shall be saved in the "object" of file sec_test.js and it shall not be readable or writable just execution-able. Is this a correct way?
Question 1:
Is it possible to get the secret somehow during execution from the testing_sec_test.js?
Question 2:
is it possible to have a constructor-ish function in sec_test.js ?
file: sec_test.js
module.exports = function (string) {
var module = {};
let secret = null;
module.get_secret_length = function (callback) {
generate_secret();
if(secret == null){
const json_err = {
"Success":false,
"error":"generating secret failed"
};
callback(json_err,null);
}else{
const json_err = {
"Success":true,
"result":"secret has been generated",
"secret_length":get_secret_length()
};
callback(json_err,null);
}
}
function generate_secret(){
if(secret == null){
secret = getRandomString()+string+getRandomString();
}
}
function get_secret_length(){
return secret.length;
}
function getRandomString(){
const length = Math.floor(Math.random() * Math.floor(200));
const characters_allowed = '#1#2$3&/=?:.;,+_-><~*^|4567890'+
'qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM';
let random_string = "";
for(let i =0;i<length;i++){
let random_nbr = Math.floor(Math.random() * Math.floor(characters_allowed.length));
random_string += characters_allowed.charAt(random_nbr);
}
return random_string;
}
return module;
};
file: testing_sec_test.js
const sec_test = require('./sec_test')("IS THIS SECRET A PRIVATE VARIABLE");
console.log(sec_test.get_secret_length.toString());
sec_test.get_secret_length(function(err,result){
if(err){
console.log(err);
}else{
console.log(result);
}
});
---------------------------------------------------------------
I Guess i have to formulate my question a little better,, sorry
Question 1: Is it possible to get the key or ivKey AFTER the object has been required and the parameter has been inputed. Or is this object not safe to use becase its key or ivKey is public accessable?
file: testing_sec_test.js
//lets pretend that these keys is written in from the terminal to the object and are NOT hardcoded in the code!.
let sec_Obj = {
"key": '1234zr3p67VC61jmV54rIYu1545x4TlY',
"ivKey": "123460iP0h6vJoEa",
"salt": "1kg8kfjfd2js93zg7sdg485sd74g63d2",
"key_iterations": 87923
}
const sec_test = require('./sec_test')(sec_Obj);
sec_Obj = null;
console.log(sec_test);
let plain_text = "This is a national secret";
console.log("plain_text == "+plain_text);
sec_test.encrypt(plain_text,function(err,encrypted){
if(err){
console.log(err);
}else{
console.log("encrypted == "+encrypted);
sec_test.decrypt(encrypted,function(err,decrypted){
if(err){
console.log(err);
}else{
console.log("decrypted == "+decrypted);
}
});
}
});
file: sec_test.js
const crypto = require('crypto');
module.exports = function (keysObj) {
//is the parameter keysObj private??
var module = {};
module.encrypt = function (clearData,callback) {
let str_encoding = "utf8";
let encoding = "base64";
try {
let encipher = crypto.createCipheriv('aes-256-ctr', getPrivateKey(), getPrivateIvKey());
let result = encipher.update(clearData, str_encoding, encoding);
result += encipher.final(encoding);
callback(null,result);
} catch (error) {
callback({"success":false,"error":error},null);
}
}
module.decrypt = function(encrypted,callback) {
let str_encoding = "utf8";
let encoding = "base64";
try {
let decipher = crypto.createDecipheriv('aes-256-ctr',getPrivateKey(), getPrivateIvKey());
let result = decipher.update(encrypted, encoding, str_encoding);
result += decipher.final(str_encoding);
callback(null,result);
} catch (error) {
callback({"success":false,"error":error},null);
}
}
//is this a private function
function getPrivateKey(){
return crypto.pbkdf2Sync(keysObj['key'], keysObj['salt'], keysObj['key_iterations'], 32, 'sha512');
}
//is this a private function
function getPrivateIvKey(){
return new Buffer(keysObj['ivKey']);
}
return module;
};
Simple example
var privateVar = 'private';
module.exports = {
test:function(){
console.log('I am '+privateVar);
}
}
var test = require('./test.js');
//logs i am private
test.test()
//logs undefined
test.privateVar

how to run at command through chrome serial api

i want to run at command at my hardware thorugh crome serial api
I use this Opensource code
https://github.com/GoogleChrome/chrome-app-samples/tree/master/servo
this working only for only integer
i want to pass string in the serial port my code is like following
var connectionId = -1;
function setPosition(position) {
var buffer = new ArrayBuffer(1);
var uint8View = new Uint8Array(buffer);
uint8View[0] = '0'.charCodeAt(0) + position;
chrome.serial.write(connectionId, buffer, function() {});
};
function setTxt(data) {
// document.getElementById('txt').innerHTML = data;
var bf = str2ab(data)
chrome.serial.write(connectionId, bf, function() {});
};
function str2ab(str) {
len = str.length;
var buf = new ArrayBuffer(len*2); // 2 bytes for each char
var bufView = new Uint16Array(buf);
for (var i=0, strLen=str.length; i<strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
function onRead(readInfo) {
var uint8View = new Uint8Array(readInfo.data);
var value1 = String.fromCharCode(uint8View[0])
var value = uint8View[0] - '0'.charCodeAt(0);
var rotation = value * 18.0;
// var dataarr = String.fromCharCode.apply(null, new Uint16Array(readInfo.data));
//alert(rotation);
if(uint8View[0])
document.getElementById('txt').innerHTML = document.getElementById('txt').innerHTML + value1;
document.getElementById('image').style.webkitTransform =
'rotateZ(' + rotation + 'deg)';
// document.getElementById('txt').innerHTML=uint8View[0];
// Keep on reading.
chrome.serial.read(connectionId, 1, onRead);
};
function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
function onOpen(openInfo) {
connectionId = openInfo.connectionId;
if (connectionId == -1) {
setStatus('Could not open');
return;
}
setStatus('Connected');
setPosition(0);
chrome.serial.read(connectionId, 1, onRead);
};
function setStatus(status) {
document.getElementById('status').innerText = status;
}
function buildPortPicker(ports) {
var eligiblePorts = ports.filter(function(port) {
return !port.match(/[Bb]luetooth/);
});
var portPicker = document.getElementById('port-picker');
eligiblePorts.forEach(function(port) {
var portOption = document.createElement('option');
portOption.value = portOption.innerText = port;
portPicker.appendChild(portOption);
});
portPicker.onchange = function() {
if (connectionId != -1) {
chrome.serial.close(connectionId, openSelectedPort);
return;
}
openSelectedPort();
};
}
function openSelectedPort() {
var portPicker = document.getElementById('port-picker');
var selectedPort = portPicker.options[portPicker.selectedIndex].value;
chrome.serial.open(selectedPort, onOpen);
}
onload = function() {
var tv = document.getElementById('tv');
navigator.webkitGetUserMedia(
{video: true},
function(stream) {
tv.classList.add('working');
document.getElementById('camera-output').src =
webkitURL.createObjectURL(stream);
},
function() {
tv.classList.add('broken');
});
document.getElementById('position-input').onchange = function() {
setPosition(parseInt(this.value, 10));
};
document.getElementById('txt-input').onchange = function() {
setTxt(this.value);
// document.getElementById('txt').innerHTML = this.value;
};
chrome.serial.getPorts(function(ports) {
buildPortPicker(ports)
openSelectedPort();
});
};
string is the passing through serial but this command not run without enter press how to do it any one know
thanks in advance :)
need a \n at the end of string
example:
writeSerial( '#;Bit_Test;*;1;' + '\n' );
take a look at this project http://www.dataino.it/help/document_tutorial.php?id=13

Categories

Resources