Skip to content

Instantly share code, notes, and snippets.

@shahinghasemi
Last active October 18, 2023 08:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save shahinghasemi/8008ba4918feeed08b14f7b9b3a32610 to your computer and use it in GitHub Desktop.
Save shahinghasemi/8008ba4918feeed08b14f7b9b3a32610 to your computer and use it in GitHub Desktop.
FullStack AES-GCM Encryption Decryption using NodeJS and Browser standard libraries (native crypto API)
//----------------------------------------------------------------
// ------------------- ServerSide(NODE.JS) -------------------
//----------------------------------------------------------------
function encrypt(message){
const KEY = crypto.randomBytes(32)
const IV = crypto.randomBytes(16)
const ALGORITHM = 'aes-256-gcm';
const cipher = crypto.createCipheriv(ALGORITHM, KEY, IV);
let encrypted = cipher.update(message, 'utf8', 'hex');
encrypted += cipher.final('hex');
const tag = cipher.getAuthTag()
let output = {
encrypted,
KEY: KEY.toString('hex'),
IV: IV.toString('hex'),
TAG: tag.toString('hex'),
}
return output;
}
//------------------------------------------------------------------
// ------------------- ClientSide -------------------
//------------------------------------------------------------------
function decrypt() {
let KEY = hexStringToArrayBuffer(data.KEY);
let IV = hexStringToArrayBuffer(data.IV);
let encrypted = hexStringToArrayBuffer(data.encrypted + data.TAG);
window.crypto.subtle.importKey('raw', KEY, 'AES-GCM', true, ['decrypt']).then((importedKey)=>{
console.log('importedKey: ', importedKey);
window.crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: IV,
},
importedKey,
encrypted
).then((decodedBuffer)=>{
let plaintext = new TextDecoder('utf8').decode(decodedBuffer);
console.log('plainText: ', plaintext);
})
})
function hexStringToArrayBuffer(hexString) {
hexString = hexString.replace(/^0x/, '');
if (hexString.length % 2 != 0) {
console.log('WARNING: expecting an even number of characters in the hexString');
}
var bad = hexString.match(/[G-Z\s]/i);
if (bad) {
console.log('WARNING: found non-hex characters', bad);
}
var pairs = hexString.match(/[\dA-F]{2}/gi);
var integers = pairs.map(function(s) {
return parseInt(s, 16);
});
var array = new Uint8Array(integers);
return array.buffer;
}
@shahinghasemi
Copy link
Author

@Goutham0110 The TLS is not a concern, the time that the user can decrypt the data is the real concern. In our case, to prevent the server load we needed to send the encrypted data to the users first, then users request the keys from the server afterward.
This way the traffic is spread.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment