Skip to content

Instantly share code, notes, and snippets.

@CoolHandDev
Forked from AndiDittrich/AesUtil.js
Created December 29, 2018 01:44
Show Gist options
  • Select an option

  • Save CoolHandDev/9fd22b9f05c1b569a0ff292286109976 to your computer and use it in GitHub Desktop.

Select an option

Save CoolHandDev/9fd22b9f05c1b569a0ff292286109976 to your computer and use it in GitHub Desktop.

Revisions

  1. Andi Dittrich revised this gist Jun 6, 2018. 1 changed file with 12 additions and 4 deletions.
    16 changes: 12 additions & 4 deletions AesUtil.js
    Original file line number Diff line number Diff line change
    @@ -1,15 +1,23 @@
    // AES Encryption/Decryption with AES-256-GCM using random Initialization Vector + Salt
    // -----
    // ----------------------------------------------------------------------------------------
    // the encrypted datablock is base64 encoded for easy data exchange.
    // if you have the option to store data binary save consider to remove the encoding to reduce storage size
    // -----
    // ----------------------------------------------------------------------------------------
    // format of encrypted data - used by this example. not an official format
    //
    // +--------------------+-----------------------+----------------+----------------+
    // | SALT | Initialization Vector | Auth Tag | Payload |
    // | Used to derive key | AES GCM XOR Init | Data Integrity | Encrypted Data |
    // | 64 Bytes, random | 16 Bytes, random | 16 Bytes | (N-96) Bytes |
    // +--------------------+-----------------------+----------------+----------------+
    //
    // ----------------------------------------------------------------------------------------
    // Input/Output Vars
    //
    // MASTERKEY: the key used for encryption/decryption.
    // it has to be cryptographic safe - this means randomBytes or derived by pbkdf2 (for example)
    // TEXT: data (utf8 string) which should be encoded. modify the code to use Buffer for binary data!
    // ENCDATA: encrypted data as base64 string (format mentioned on top)

    // load the build-in crypto functions
    const _crypto = require('crypto');
    @@ -53,9 +61,9 @@ module.exports = {
    * @param Buffer masterkey
    * @returns String decrypted (original) text
    */
    decrypt: function (data, masterkey){
    decrypt: function (encdata, masterkey){
    // base64 decoding
    const bData = Buffer.from(data, 'base64');
    const bData = Buffer.from(encdata, 'base64');

    // convert data to buffers
    const salt = bData.slice(0, 64);
  2. Andi Dittrich revised this gist Jun 6, 2018. 1 changed file with 12 additions and 1 deletion.
    13 changes: 12 additions & 1 deletion AesUtil.js
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,15 @@
    // AES Encryption/Decryption with AES-256-GCM using random Initialization Vector + Salt
    // -----
    // the encrypted datablock is base64 encoded for easy data exchange.
    // if you have the option to store data binary save consider to remove the encoding to reduce storage size
    // -----
    // format of encrypted data - used by this example. not an official format
    //
    // +--------------------+-----------------------+----------------+----------------+
    // | SALT | Initialization Vector | Auth Tag | Payload |
    // | Used to derive key | AES GCM XOR Init | Data Integrity | Encrypted Data |
    // | 64 Bytes, random | 16 Bytes, random | 16 Bytes | (N-96) Bytes |
    // +--------------------+-----------------------+----------------+----------------+

    // load the build-in crypto functions
    const _crypto = require('crypto');
    @@ -44,7 +55,7 @@ module.exports = {
    */
    decrypt: function (data, masterkey){
    // base64 decoding
    const bData = new Buffer(data, 'base64');
    const bData = Buffer.from(data, 'base64');

    // convert data to buffers
    const salt = bData.slice(0, 64);
  3. Andi Dittrich revised this gist Apr 7, 2018. 1 changed file with 32 additions and 49 deletions.
    81 changes: 32 additions & 49 deletions AesUtil.js
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,7 @@
    /**
    * AES Encryption/Decryption with AES-256-GCM using random Initialization Vector + Salt
    * @type {exports}
    */
    // AES Encryption/Decryption with AES-256-GCM using random Initialization Vector + Salt

    // load the build-in crypto functions
    var crypto = require('crypto');
    const _crypto = require('crypto');

    // encrypt/decrypt functions
    module.exports = {
    @@ -16,34 +13,27 @@ module.exports = {
    * @returns String encrypted text, base64 encoded
    */
    encrypt: function (text, masterkey){
    try {
    // random initialization vector
    var iv = crypto.randomBytes(12);
    // random initialization vector
    const iv = _crypto.randomBytes(16);

    // random salt
    var salt = crypto.randomBytes(64);
    // random salt
    const salt = _crypto.randomBytes(64);

    // derive key: 32 byte key length - in assumption the masterkey is a cryptographic and NOT a password there is no need for
    // a large number of iterations. It may can replaced by HKDF
    var key = crypto.pbkdf2Sync(masterkey, salt, 2145, 32, 'sha512');
    // derive key: 32 byte key length - in assumption the masterkey is a cryptographic and NOT a password there is no need for
    // a large number of iterations. It may can replaced by HKDF
    const key = _crypto.pbkdf2Sync(masterkey, salt, 2145, 32, 'sha512');

    // AES 256 GCM Mode
    var cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
    // AES 256 GCM Mode
    const cipher = _crypto.createCipheriv('aes-256-gcm', key, iv);

    // encrypt the given text
    var encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()]);
    // encrypt the given text
    const encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()]);

    // extract the auth tag
    var tag = cipher.getAuthTag();
    // extract the auth tag
    const tag = cipher.getAuthTag();

    // generate output
    return Buffer.concat([salt, iv, tag, encrypted]).toString('base64');

    }catch(e){
    }

    // error
    return null;
    // generate output
    return Buffer.concat([salt, iv, tag, encrypted]).toString('base64');
    },

    /**
    @@ -53,32 +43,25 @@ module.exports = {
    * @returns String decrypted (original) text
    */
    decrypt: function (data, masterkey){
    try {
    // base64 decoding
    var bData = new Buffer(data, 'base64');

    // convert data to buffers
    var salt = bData.slice(0, 64);
    var iv = bData.slice(64, 76);
    var tag = bData.slice(76, 92);
    var text = bData.slice(92);

    // derive key using; 32 byte key length
    var key = crypto.pbkdf2Sync(masterkey, salt , 2145, 32, 'sha512');
    // base64 decoding
    const bData = new Buffer(data, 'base64');

    // AES 256 GCM Mode
    var decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
    decipher.setAuthTag(tag);
    // convert data to buffers
    const salt = bData.slice(0, 64);
    const iv = bData.slice(64, 80);
    const tag = bData.slice(80, 96);
    const text = bData.slice(96);

    // encrypt the given text
    var decrypted = decipher.update(text, 'binary', 'utf8') + decipher.final('utf8');
    // derive key using; 32 byte key length
    const key = _crypto.pbkdf2Sync(masterkey, salt , 2145, 32, 'sha512');

    return decrypted;
    // AES 256 GCM Mode
    const decipher = _crypto.createDecipheriv('aes-256-gcm', key, iv);
    decipher.setAuthTag(tag);

    }catch(e){
    }
    // encrypt the given text
    const decrypted = decipher.update(text, 'binary', 'utf8') + decipher.final('utf8');

    // error
    return null;
    return decrypted;
    }
    };
  4. Andi Dittrich renamed this gist Jun 29, 2015. 1 changed file with 24 additions and 15 deletions.
    39 changes: 24 additions & 15 deletions gistfile1.js → AesUtil.js
    Original file line number Diff line number Diff line change
    @@ -8,6 +8,13 @@ var crypto = require('crypto');

    // encrypt/decrypt functions
    module.exports = {

    /**
    * Encrypts text by given key
    * @param String text to encrypt
    * @param Buffer masterkey
    * @returns String encrypted text, base64 encoded
    */
    encrypt: function (text, masterkey){
    try {
    // random initialization vector
    @@ -24,13 +31,13 @@ module.exports = {
    var cipher = crypto.createCipheriv('aes-256-gcm', key, iv);

    // encrypt the given text
    var encrypted = cipher.update(text, 'utf8', 'hex') + cipher.final('hex');
    var encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()]);

    // extract the auth tag
    var tag = cipher.getAuthTag();

    // generate output
    return salt.toString('hex') + ':' + iv.toString('hex') + ':' + tag.toString('hex') + ':' + encrypted;
    return Buffer.concat([salt, iv, tag, encrypted]).toString('base64');

    }catch(e){
    }
    @@ -39,30 +46,32 @@ module.exports = {
    return null;
    },

    /**
    * Decrypts text by given key
    * @param String base64 encoded input data
    * @param Buffer masterkey
    * @returns String decrypted (original) text
    */
    decrypt: function (data, masterkey){
    try {
    // split input data data
    var parts = data.split(':');

    if (parts.length != 4){
    return null;
    }
    // base64 decoding
    var bData = new Buffer(data, 'base64');

    // convert data to buffers
    var salt = new Buffer(parts[0], 'hex');
    var iv = new Buffer(parts[1], 'hex');
    var tag = new Buffer(parts[2], 'hex');
    var text = parts[3];
    var salt = bData.slice(0, 64);
    var iv = bData.slice(64, 76);
    var tag = bData.slice(76, 92);
    var text = bData.slice(92);

    // derive key using; 32 byte key length
    var key = crypto.pbkdf2Sync(masterkey, salt , 2145, 32, 'sha512');

    // AES 256 GCM Mode
    var decipher = crypto.createDecipheriv('aes-256-gcm', key, iv, 'hex');
    decipher.setAuthTag(tag, 'hex');
    var decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
    decipher.setAuthTag(tag);

    // encrypt the given text
    var decrypted = decipher.update(text, 'hex', 'utf8') + decipher.final('utf8');
    var decrypted = decipher.update(text, 'binary', 'utf8') + decipher.final('utf8');

    return decrypted;

  5. Andi Dittrich revised this gist Jun 26, 2015. No changes.
  6. Andi Dittrich created this gist Jun 26, 2015.
    75 changes: 75 additions & 0 deletions gistfile1.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,75 @@
    /**
    * AES Encryption/Decryption with AES-256-GCM using random Initialization Vector + Salt
    * @type {exports}
    */

    // load the build-in crypto functions
    var crypto = require('crypto');

    // encrypt/decrypt functions
    module.exports = {
    encrypt: function (text, masterkey){
    try {
    // random initialization vector
    var iv = crypto.randomBytes(12);

    // random salt
    var salt = crypto.randomBytes(64);

    // derive key: 32 byte key length - in assumption the masterkey is a cryptographic and NOT a password there is no need for
    // a large number of iterations. It may can replaced by HKDF
    var key = crypto.pbkdf2Sync(masterkey, salt, 2145, 32, 'sha512');

    // AES 256 GCM Mode
    var cipher = crypto.createCipheriv('aes-256-gcm', key, iv);

    // encrypt the given text
    var encrypted = cipher.update(text, 'utf8', 'hex') + cipher.final('hex');

    // extract the auth tag
    var tag = cipher.getAuthTag();

    // generate output
    return salt.toString('hex') + ':' + iv.toString('hex') + ':' + tag.toString('hex') + ':' + encrypted;

    }catch(e){
    }

    // error
    return null;
    },

    decrypt: function (data, masterkey){
    try {
    // split input data data
    var parts = data.split(':');

    if (parts.length != 4){
    return null;
    }

    // convert data to buffers
    var salt = new Buffer(parts[0], 'hex');
    var iv = new Buffer(parts[1], 'hex');
    var tag = new Buffer(parts[2], 'hex');
    var text = parts[3];

    // derive key using; 32 byte key length
    var key = crypto.pbkdf2Sync(masterkey, salt , 2145, 32, 'sha512');

    // AES 256 GCM Mode
    var decipher = crypto.createDecipheriv('aes-256-gcm', key, iv, 'hex');
    decipher.setAuthTag(tag, 'hex');

    // encrypt the given text
    var decrypted = decipher.update(text, 'hex', 'utf8') + decipher.final('utf8');

    return decrypted;

    }catch(e){
    }

    // error
    return null;
    }
    };