Skip to content

Instantly share code, notes, and snippets.

@brownhash
Created September 22, 2022 10:47
Show Gist options
  • Save brownhash/984dcc32b04702d254c4ca04491897e4 to your computer and use it in GitHub Desktop.
Save brownhash/984dcc32b04702d254c4ca04491897e4 to your computer and use it in GitHub Desktop.
AES GCM without passing the Authentication tag (Python & JS)
const crypto = require('crypto');
const assert = require('assert');
const AesGcm = (key, nonce) => {
const ALGO = 'aes-256-gcm';
const encrypt = (plaintext) => {
/*
Encrypts provided plain text with AES-GCM-256-bit encryption using the provided nonce(iv).
Returns: Cipher text appended with 16 bit autherntication tag.
*/
const cipher = crypto.createCipheriv(ALGO, key, nonce);
// append authentication tag to cipher text
let cipher_text = Buffer.concat([
cipher.update(plaintext),
cipher.final(),
cipher.getAuthTag()
]);
return cipher_text;
};
const decrypt = (cipher_text) => {
/*
Decrypts AES-GCM-256-bit encrypted ciphertext appended with 16 bit authentication tag.
Returns: Decrypted plaintext.
*/
const decipher = crypto.createDecipheriv(ALGO, key, nonce);
// extract 16 bit authentication tag from provided cipher text
let authTag = cipher_text.slice(-16);
// remove authentication tag from cipher text
cipher_text = cipher_text.slice(0, cipher_text.length - 16)
decipher.setAuthTag(authTag);
let decrypted = decipher.update(cipher_text);
return decrypted;
};
return {
encrypt,
decrypt,
};
};
module.exports = {
AesGcm,
}
if (require.main === module) {
const Key = 'someKeyThatIs32CharactersLongggg';
const Nonce = 'something'
const data = '{"string": "a random string", "boolean": True, "number": 123}'
const aesCipher = AesGcm(Buffer.from(Key, 'utf8'), Buffer.from(Nonce, 'utf8'));
const encrypted = aesCipher.encrypt(data);
const decrypted = aesCipher.decrypt(encrypted);
assert(decrypted.toString('utf-8') == data)
}
from cryptography.hazmat.primitives.ciphers import (
Cipher, algorithms, modes
)
class AesGcm:
'''
AES-GCM-256-bit cryptography helpers.
'''
@staticmethod
def encrypt(key: bytes, plaintext: bytes, nonce: bytes) -> bytes:
'''
Encrypts provided plain text with AES-GCM-256-bit encryption using the provided nonce(iv).
Returns: Cipher text appended with 16 bit autherntication tag.
'''
encryptor = Cipher(
algorithms.AES(key),
modes.GCM(initialization_vector=nonce, tag=None),
).encryptor()
cipher_text = encryptor.update(plaintext) + encryptor.finalize()
# return cipher text appended with authentication tag
return cipher_text + encryptor.tag
@staticmethod
def decrypt(key: bytes, cipher_text: bytes, nonce: bytes) -> bytes:
'''
Decrypts AES-GCM-256-bit encrypted ciphertext appended with 16 bit authentication tag.
Returns: Decrypted plaintext.
'''
# extract 16 bit authentication tag from provided cipher text
tag = cipher_text[-16:]
# remove authentication tag from cipher text
cipher_text = cipher_text[:len(cipher_text)-16]
decryptor = Cipher(
algorithms.AES(key),
modes.GCM(initialization_vector=nonce, tag=tag),
).decryptor()
return decryptor.update(cipher_text) + decryptor.finalize()
if __name__ == '__main__':
KEY = 'someKeyThatIs32CharactersLongggg'
NONCE = 'something'
JSON_DATA = '{"string": "a random string", "boolean": True, "number": 123}'
ciphertext = AesGcm.encrypt(
key=bytes(KEY, encoding='utf8'),
plaintext=bytes(JSON_DATA, encoding='utf8'),
nonce=bytes(NONCE, encoding='utf8')
)
decrypted = AesGcm.decrypt(
key=bytes(KEY, encoding='utf8'),
cipher_text=ciphertext,
nonce=bytes(NONCE, encoding='utf8')
)
assert decrypted.decode('utf8') == JSON_DATA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment