Created
September 22, 2022 10:47
-
-
Save brownhash/984dcc32b04702d254c4ca04491897e4 to your computer and use it in GitHub Desktop.
AES GCM without passing the Authentication tag (Python & JS)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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