Last active
October 16, 2024 11:42
-
-
Save tmarthal/cf5a610c5c5ab1e661a6351c96200706 to your computer and use it in GitHub Desktop.
PyCrypto AES256 Encoding with Initialization Vectors Matching Spring Security
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
class AesCrypt256: | |
#Based on https://gist.github.com/pfote/5099161 | |
BLOCK_SIZE = 16 | |
# To use the null/x00 byte array for the IV | |
default_initialization_vector = False | |
def __init__(self, default_initialization_vector=False): | |
self.default_initialization_vector = default_initialization_vector | |
def pkcs5_pad(self,s): | |
return s + (self.BLOCK_SIZE - len(s) % self.BLOCK_SIZE) * chr(self.BLOCK_SIZE - len(s) % self.BLOCK_SIZE) | |
def pkcs5_unpad(self, s): | |
# from https://jhafranco.com/2012/01/16/aes-implementation-in-python/ | |
return "".join(chr(e) for e in s[:-s[-1]]) | |
def _encrypt(self, key, value, iv): | |
cipher = AES.new(key, AES.MODE_CBC, iv) | |
crypted = cipher.encrypt(self.pkcs5_pad(value).encode('utf-8')) | |
# check if empty/null initialization vector, and do not prepend if null | |
if all(v == 0 for v in iv): | |
return crypted | |
else: | |
# prepend the initialization vector | |
return iv+crypted | |
def _decrypt(self, key, value, iv): | |
cipher = AES.new(key, AES.MODE_CBC, iv) | |
# unpad the bytes, throw away garbage at end | |
return self.pkcs5_unpad(cipher.decrypt(value)) | |
def encrypt(self, key, value): | |
if self.default_initialization_vector: | |
return self._encrypt(key, value, bytes(bytearray(16))) | |
else: | |
iv = Random.get_random_bytes(16) | |
return self._encrypt(key, value, iv) | |
def decrypt(self, key, value): | |
if self.default_initialization_vector: | |
# we do not have an IV present | |
default_iv = bytes(bytearray(16)) | |
return self._decrypt(key, value, default_iv) | |
else: | |
iv = value[:16] | |
crypted = value[16:] | |
return self._decrypt(key, crypted, iv) | |
def encryptHex(self, key, value): | |
return binascii.hexlify(self.encrypt(key, value)) | |
def decryptHex(self, key, value): | |
return self.decrypt(key, binascii.unhexlify(value)) |
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
>>> encryptor = AesCrypt256(default_initialization_vector=False) | |
>>> encryptor.decryptHex(key,'98937740c652f6a17febce5013d7d13aed67a8867365e5a89374e658ad74f742') | |
'foo' | |
>>> encryptor.decryptHex(key,'e3673e05560e1d24f26b4a6ed300a298c17cb9d7be9a52f11d9358421a79c015') | |
'foo' | |
>>> encryptor = AesCrypt256(default_initialization_vector=True) | |
>>> encryptor.decryptHex(key,'a070fa1b40dafa6d7c55ee697c4cb448') | |
'foo' |
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
b'a070fa1b40dafa6d7c55ee697c4cb448' | |
b'a070fa1b40dafa6d7c55ee697c4cb448' | |
b'a070fa1b40dafa6d7c55ee697c4cb448' |
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
encryptor = AesCrypt256(default_initialization_vector=True) | |
for _ in range(3): | |
print(encryptor.encryptHex(key, 'foo')) |
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
b'41605549007b8d29038777dfd57a1d346fa6a3a34508c311ff5492be281fb269' | |
b'4c11d16fc12d8456bb636851943aebb2e94c39e8c7e5242cf01b736f0fae4df1' | |
b'054f1938a77f98985a6dd920694d3e5cd70f9e2a95fbf285df743d6f9e648b36' |
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
# Random symmetric test | |
password = 'password' | |
salt = binascii.unhexlify('5c0744940b5c369b') | |
iterations = 1024 | |
# AES uses 256 bit encryption, 32 bytes | |
key = PBKDF2(password=password, salt=salt, dkLen=32, count=iterations) | |
encryptor = AesCrypt256(default_initialization_vector=False) | |
for _ in range(3): | |
print(encryptor.encryptHex(key, 'foo')) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment