Last active
November 15, 2024 13:47
-
-
Save sumanmukherjee03/dd16d6c732a1055b6af97daba484809d to your computer and use it in GitHub Desktop.
AES GCM example in python and go
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
package main | |
import ( | |
"crypto/aes" | |
"crypto/cipher" | |
"fmt" | |
"reflect" | |
"strconv" | |
"time" | |
) | |
const ( | |
KEY string = "AES256Key-32Characters1234567890" | |
NONCE_BYTE_SIZE uint = 12 | |
) | |
func decrypt(aesgcm cipher.AEAD, ciphertext []byte, nonce []byte) ([]byte, error) { | |
plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil) | |
return plaintext, err | |
} | |
func encrypt(aesgcm cipher.AEAD, plaintext []byte, nonce []byte) []byte { | |
plaintext = aesgcm.Seal(plaintext[:0], nonce, plaintext, nil) | |
return plaintext | |
} | |
func checkEncryptDecrypt(aesgcm cipher.AEAD, text string, nonce []byte) { | |
input := []byte(text) | |
expectation := []byte(text) | |
result, err := decrypt(aesgcm, encrypt(aesgcm, input, nonce), nonce) | |
if err != nil { | |
panic(err.Error()) | |
} | |
if !reflect.DeepEqual(result, expectation) { | |
fmt.Errorf("Expected %x but got %x", input, expectation) | |
} else { | |
fmt.Println("Passes test") | |
} | |
} | |
func main() { | |
key := []byte(KEY) | |
block, err := aes.NewCipher(key) | |
if err != nil { | |
panic(err.Error()) | |
} | |
aesgcm, err := cipher.NewGCM(block) | |
if err != nil { | |
panic(err.Error()) | |
} | |
type testargs struct { | |
text string | |
nonce []byte | |
} | |
var testargslist = []testargs{ | |
testargs{ | |
text: "http://rainandrhyme.com?foo=bar&blah=blur", | |
nonce: []byte(strconv.Itoa(int(time.Now().UTC().Unix())))[:NONCE_BYTE_SIZE], | |
}, | |
testargs{ | |
text: "http://sumanmukherjee.tech?foo=blah&bar=baz", | |
nonce: []byte(strconv.Itoa(int(time.Now().UTC().Add(60).Unix())))[:NONCE_BYTE_SIZE], | |
}, | |
} | |
for _, ta := range testargslist { | |
checkEncryptDecrypt(aesgcm, ta.text, ta.nonce) | |
} | |
} |
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
#!/usr/bin/env python | |
import os | |
import sys | |
import datetime | |
import time | |
from cryptography.hazmat.backends import default_backend | |
from cryptography.hazmat.primitives.ciphers import ( | |
Cipher, algorithms, modes | |
) | |
KEY = "AES256Key-32Characters1234567890" | |
NONCE_BYTE_SIZE = 12 | |
def encrypt(cipher, plaintext, nonce): | |
cipher.mode = modes.GCM(nonce) | |
encryptor = cipher.encryptor() | |
ciphertext = encryptor.update(plaintext) | |
return (cipher, ciphertext, nonce) | |
def decrypt(cipher, ciphertext, nonce): | |
cipher.mode = modes.GCM(nonce) | |
decryptor = cipher.decryptor() | |
return decryptor.update(ciphertext) | |
def checkEncryptDecrypt(cipher, text, nonce): | |
assert decrypt(*encrypt(cipher, text, nonce)) == text | |
print('Passes test') | |
def main(args): | |
cipher = Cipher( | |
algorithms.AES(KEY), | |
None, | |
backend=default_backend() | |
) | |
arr = [ | |
(b'http://rainandrhyme.com?foo=bar&blah=blur', str(time.mktime(datetime.datetime(2014, 3, 17).timetuple()))[:NONCE_BYTE_SIZE]), | |
(b'http://sumanmukherjee.tech?foo=blah&bar=baz', str(time.mktime(datetime.datetime(2017, 11, 7).timetuple()))[:NONCE_BYTE_SIZE])] | |
for (text, nonce) in arr: | |
checkEncryptDecrypt(cipher, text, nonce) | |
if __name__ == '__main__': | |
main(sys.argv[1:]) |
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
package main | |
import ( | |
"crypto/aes" | |
"crypto/cipher" | |
"strconv" | |
"testing" | |
"time" | |
) | |
func setup() (cipher.AEAD, []byte) { | |
key := []byte(KEY) | |
nonce := []byte(strconv.Itoa(int(time.Now().UTC().Unix())))[:NONCE_BYTE_SIZE] | |
block, err := aes.NewCipher(key) | |
if err != nil { | |
panic(err.Error()) | |
} | |
aesgcm, err := cipher.NewGCM(block) | |
if err != nil { | |
panic(err.Error()) | |
} | |
return aesgcm, nonce | |
} | |
func benchmarkEncrypt(b *testing.B) { | |
text := "http://rainandrhyme.com?foo=bar&blah=blur" | |
aesgcm, nonce := setup() | |
input := []byte(text) | |
for i := 0; i < b.N; i++ { | |
encrypt(aesgcm, input, nonce) | |
} | |
} | |
func benchmarkDecrypt(b *testing.B) { | |
text := "http://rainandrhyme.com?foo=bar&blah=blur" | |
aesgcm, nonce := setup() | |
input := []byte(text) | |
encrypted_text := encrypt(aesgcm, input, nonce) | |
for i := 0; i < b.N; i++ { | |
decrypt(aesgcm, encrypted_text, nonce) | |
} | |
} | |
func BenchmarkEncryptDecrypt(b *testing.B) { | |
b.Run("cipher", func(b *testing.B) { | |
b.Run("Encrypt", benchmarkEncrypt) | |
b.Run("Decrypt", benchmarkDecrypt) | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment