Node-uuid provides an excellent package to generate uuid
https://github.com/broofa/node-uuid
// Generate a v4 (random) id
uuid.v4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'
However, it does not provide a way to encode it in base64 or alphanumeric string.
Is there an easy way to do this?
Install;
https://github.com/RGBboy/urlsafe-base64
Then;
var uuid = require('node-uuid');
var base64 = require('urlsafe-base64');
base64.encode(Buffer(uuid.v4()));
Related
I am working out a custom hybrid encryption system. I've got symmetric encryption & asymmetric encryption & decryption all handled server-side. All I need to work out now is symmetric decryption.
I got some trouble because my client is sending symmetric key, iv & data all in string format (after asymmetric decryption), but CryptoJS is very touchy with it's encoding. It's also very confusing and vague as far as documentation goes- at least for a relatively new developer. I just can't figure out what encoding CryptoJS wants for each argument. I figure I should have guessed right by now, but no.
Docs
Some help I've gotten previously
I'm requesting help getting the encoding right so that I can decrypt with the following. And thanks a lot for any assistance.
Example of data after asymmetric decryption as per below (throw away keys):
symmetricKey: bDKJVr5wFtQZaPrs4ZoMkP2RjtaYpXo5HHKbzrNELs8=,
symmetricNonce: Z8q66bFkbEqQiVbrUrts+A==,
dataToReceive: "hX/BFO7b+6eYV1zt3+hu3o5g61PFB4V3myyU8tI3W7I="
exports.transportSecurityDecryption = async function mmTransportSecurityDecryption(dataToReceive, keys) {
const JSEncrypt = require('node-jsencrypt');
const CryptoJS = require("crypto-js");
// Asymmetrically decrypt symmetric cypher data with server private key
const privateKeyQuery = new Parse.Query("ServerPrivateKey");
const keyQueryResult = await privateKeyQuery.find({useMasterKey: true});
const object = keyQueryResult[0];
const serverPrivateKey = object.get("key");
const crypt = new JSEncrypt();
crypt.setPrivateKey(serverPrivateKey);
let decryptedDataString = crypt.decrypt(keys);
let decryptedData = JSON.parse(decryptedDataString);
// Symmetrically decrypt transit data
let symmetricKey = decryptedData.symmetricKey;
let symmetricNonce = decryptedData.symmetricNonce;
// Works perfectly till here <---
var decrypted = CryptoJS.AES.decrypt(
CryptoJS.enc.Hex.parse(dataToReceive),
CryptoJS.enc.Utf8.parse(symmetricKey),
{iv: CryptoJS.enc.Hex.parse(symmetricNonce)}
);
return decrypted.toString(CryptoJS.enc.Utf8);
}
You are using the wrong encoders for data, key and IV. All three are Base64 encoded (and not hex or Utf8). So apply the Base64 encoder.
The ciphertext must be passed to CryptoJS.AES.decrypt() as a CipherParams object or alternatively Base64 encoded, which is implicitly converted to a CipherParams object.
When both are fixed, the plain text is: "[\"001\",\"001\"]".
var symmetricKey = "bDKJVr5wFtQZaPrs4ZoMkP2RjtaYpXo5HHKbzrNELs8="
var symmetricNonce = "Z8q66bFkbEqQiVbrUrts+A=="
var dataToReceive = "hX/BFO7b+6eYV1zt3+hu3o5g61PFB4V3myyU8tI3W7I="
var decrypted = CryptoJS.AES.decrypt(
dataToReceive, // pass Base64 encoded
//{ciphertext: CryptoJS.enc.Base64.parse(dataToReceive)}, // pass as CipherParams object, works also
CryptoJS.enc.Base64.parse(symmetricKey),
{iv: CryptoJS.enc.Base64.parse(symmetricNonce)}
);
console.log(decrypted.toString(CryptoJS.enc.Utf8));
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
I am currently using NPM module crypto-js to encrypt strings. The codes are the following:
CryptoJS.AES.encrypt("hello", "secrete_key").toString()
This yields to an encrypted string of: U2FsdGVkX1/G276++MaPasgSVxcPUgP72A1wMaB8aAM=
Notice that in the encrypted string, there are special symbols such as / + and =. These generated special symbols cause a problem in my app. Is there a way that I can encrypt a string into only alphanumericals? I like the way crypto-js is doing, since it is simple. I only need to feed in the string, and a password hash. If crypto-js cannot, what other modules can achieve this in a simple and straight-forward way?
CryptoJS also includes utilities for encoding/decoding so you can convert your encrypted string to a URL-safe format. See the CryptoJS docs for more info.
For example:
var CryptoJS = require("crypto-js");
let encrypted = CryptoJS.AES.encrypt("hello", "secrete_key").toString()
var encoded = CryptoJS.enc.Base64.parse(encrypted).toString(CryptoJS.enc.Hex);
console.log(encrypted)
console.log(encoded)
var decoded = CryptoJS.enc.Hex.parse(encoded).toString(CryptoJS.enc.Base64);
var decrypted = CryptoJS.AES.decrypt(decoded, "secrete_key").toString(CryptoJS.enc.Utf8);
console.log(decoded)
console.log(decrypted)
I am looking for standard utility for supporting the encryption & decryption based on the below algorithm in node server side.
algorithm: aes-256-gcm
using the createCipheriv, createDecipheriv from nodejs crypto module.
Please suggest some working references
The utility need to build it from your side, and based on your needs below are the small code may help you to build the utility:
const crypto = require('crypto');
// This two value (ivValueEn , ivValueDe) should be same, to decode the text properly!
// you can generate any strong value and past it at the same place of you can have it from the config value.
const ivValueEn = "c5949f09a7e67318888c5949f09a7e6c09ca51e602867318888c5949f09a7e6c09ca51e602867318888";
const ivValueDe = "c5949f09a7e6c09ca51e602867318888c5949f09a7e6c09ca51e602867319ca51e602867318888";
// insert your key here, better to chose a strong key
const keyValue = "c5949f09a7e6c09a7e6c09ca51e602867318888c5949f09a7e6c09ca51e602867318888";
// slicing are not required you can remove the slice(0,64) part & the console.log as well
const alog = 'aes-256-gcm'
const ivEn = ivValueEn.toString('hex').slice(0,64); console.log(ivEn);
const ivDe = ivValueDe.toString('hex').slice(0,64); console.log(ivDe);
// The one that working with me correctly is to slicing the key to (32) characters.
const key = keyValue.slice(0,32);
const cipher = crypto.createCipheriv(alog,key,ivEn);
const decipher = crypto.createDecipheriv (alog,key,ivDe);
I am developing an app, in which users can post pics. So I want to ensure that every time the pic gets unique name. In PHP I use to concatenate timestamp with userId. But in node.js I am not getting the method to convert timestamp to string. So kindly suggest a way to ensure that my files don't get duplicate names.
One of the solutions would be to use UUID for a file name. But that of course depends on your applications requirements or constraints (naming convention etc.). However, if UUID as a file name would be acceptable, I recommend using node-uuid library (very easy to use!).
Sample code:
var uuidv4 = require('uuid/v4');
var filename = uuidv4() + '.png'
It is safe to use UUID as a unique identifier. You can find more on that on SO e.g. How unique is UUID?
Alternative solution (where name uniqueness is a requirement) would be to use another node.js library: flake-idgen which generates conflict-free ids based on the current timestamp. That solution guarantees unique numbers.
The solution is also very efficient, allows to generate up to 4096 ids in a millisecond per generator (you can have up to 1024 unique generators).
I hope that will help.
In node:
timestamp = new Date().getTime().toString();
If you want to use timestamp uuid's use this
var uuid = require('uuid');
// Generate a v1 (time-based) id
uuid.v1(); // -> '6c84fb90-12c4-11e1-840d-7b25c5ee775a'
// Generate a v4 (random) id
uuid.v4(); // -> '110ec58a-a0f2-4ac4-8393-c866d813b8d1'
//imageExt your file extension;
const imageName = Date.now() + imageExt;
Date.now() return time in milliseconds since 1st January 1970,
if the server is fast enough to process 2 images in less than 1 millisecond you will loose an image because they both will have the same name,
the better way to do this is by using uuidv4
const { v4: uuidv4 } = require("uuid");
const imageName = uuidv4() + imageExt; // ⇨ '1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed.jpg'
uuid chance for name colision is extremely unlikely to happen.
I am having an issue generating the correct signature in NodeJS (using crypto.js) when the text I am trying to encrypt has accented characters (such as ä,ï,ë)
generateSignature = function (str, secKey) {
var hmac = crypto.createHmac('sha1', secKey);
var sig = hmac.update(str).digest('hex');
return sig;
};
This function will return the correct HMAC signature if 'str' contains no accented characters (chars such as ä,ï,ë). If there are accented chars present in the text, it will not return the correct HMAC. The accented characters are valid in UTF8 encoding so I dont know why crypto has a problem with them. It may be the case that I need to somehow tell crypto that I am signing utf8 encoded text, but I don't know how to do this.
The exact same problem is described in this post: NodeJS hmac digest issue with accents
However, the post itself, as well as the answer, do not make sense to me (as they are passing the data they want to encrypt where the secret key should go).
Here is a version of the code with hard coded values for str and secKey:
var crypto = require('crypto');
str="äïë";
secKey="secret";
var hmac = crypto.createHmac('sha1', secKey);
var sig = hmac.update(new Buffer(str, 'utf8')).digest('hex');
console.log("Sig: " + sig);
console.log("Expected: 094b2ba039775bbf970a58e4a0a61b248953d30b");
// "Expected" was generated using http://hash.online-convert.com/sha1-generator
Output::
Sig: 39c9f1a6094c76534157739681456e7878557f58
Expected: 094b2ba039775bbf970a58e4a0a61b248953d30b
Thanks
The default encoding used by the crypto module is usually 'binary'. So, you'll have to specify 'utf-8' via a Buffer to use it as the encoding:
var sig = hmac.update(new Buffer(str, 'utf-8')).digest('hex');
That's what the answer for the other question was demonstrating, just for the key:
var hmac = crypto.createHmac('sha1', new Buffer(secKey, 'utf-8'));
You can also use Buffer to view the differences:
new Buffer('äïë', 'binary')
// <Buffer e4 ef eb>
new Buffer('äïë', 'utf-8')
// <Buffer c3 a4 c3 af c3 ab>
[Edit]
Running the example code you provided, I get:
Sig: 094b2ba039775bbf970a58e4a0a61b248953d30b
Expected: 094b2ba039775bbf970a58e4a0a61b248953d30b
And, modifying it slightly, I get true:
var crypto = require('crypto');
function sig(str, key) {
return crypto.createHmac('sha1', key)
.update(new Buffer(str, 'utf-8'))
.digest('hex');
}
console.log(sig('äïë', 'secret') === '094b2ba039775bbf970a58e4a0a61b248953d30b');