shaun
shaun

Reputation: 1273

Node Express Regex to detect Invalid Characters

We are using Node module Crypto and Express to supply some query string and form name obfuscation.

'use strict';

var algorithm = 'aes-256-ctr'
    , crypto = require('crypto')
    ;

var enc = function(string, key){
    var cipher = crypto.createCipher(algorithm, key);
    var buff = Buffer.from(string, 'utf8');
    return Buffer.concat([cipher.update(buff), cipher.final()]).toString('hex').toUpperCase();
};

var dec = function(string, key){
    var decipher = crypto.createDecipher(algorithm, key);
    var buff = Buffer.from(string, 'hex');
    return Buffer.concat([decipher.update(buff), decipher.final()]).toString('utf8');
};

The key used will most likely be a random session GUID, so the query strings would only be good for as long as that session is valid.

Problem I see is that if a session GUID is different than what encoded the string, the function will still decrypt the hex string, but the result will be invalid.

Is there an regex string (to detect if any non valid characters were returned in the string) or some other way to determine if a different key was used to decode the string other than its original key?

I will be creating an express middleware soon that will look at each incoming req and determine if the req.query or req.form needs to be deciphered or not and try to determine if the query string was deciphered correctly.

Upvotes: 1

Views: 605

Answers (2)

zaph
zaph

Reputation: 112857

The usual method of ensuring the correct key is being used and/or the encrypted data has been modified is to encrypt then MAC. That means using a derivation of the encryption key to HMAC the encrypted data and appending the HMAC result to the encrypted data. When decrypting the encrypted data (less the HMAC result) is again run through the HMAC with the derived key and compared to the HMAC value that was appended. If that is successful then decrypt the data else the key or data is incorrect.

All this may be an unacceptable overhead. An alternative is to add a small data item (a canary) to the data prior to encryption and after decryption verify the value. But this is not secure against some attacks.

Upvotes: 0

rsp
rsp

Reputation: 111374

Here is what I would do. If you have a string that you want to encrypt and be able to tell that you have correctly decrypted it afterwards, instead of encrypting a bare string like 'abc' you can encrypt a JSON representation of an object like {string: 'abc'} - which will be a string: '{"string":"abc"}'

You can encode a string like this with a function like:

let encode = string => JSON.stringify({string});

Now encode('abc') returns a string: '{"string":"abc"}'

When you decrypt a string and JSON.parse() it and it results in an object that has a string property then you can be fairly sure that it is not random garbage.

After decrypting you can decode the result with a function like this:

let decode = json => { try { return JSON.parse(json).string; } catch (e) {} };

which will return the correct string for a correct JSON, but undefined for invalid JSON.

Of course you can do something like that in many different ways but this is a fairly simple way for which you wouldn't need to change your code that much.

For a more robust solution you can use JWT:

Upvotes: 2

Related Questions