from Crypto.Cipher import AES # AES crypto
from Crypto.Random import get_random_bytes
def add_padding(msg):
if len(msg) % 16 != 0:
# message length must be a factor of 16!!!
nb_of_chars_to_pad = 16 - (len(msg) % 16)
padded_msg = msg + (" " * nb_of_chars_to_pad)
return padded_msg
# message length is already a factor of 16
return msg
def encrypt_message(plaintext, key, initialization_vector):
# pad the msg if necessary
plaintext = add_padding(plaintext)
plaintext_bytes = plaintext.encode("utf_8")
# create a new AES cypher. AES hasn't been broken yet, so we're safe as long as no one knows our key!
# we use CBC mode, so we need an initialization vector.
cipher = AES.new(key, AES.MODE_CBC, initialization_vector)
ciphertext = cipher.encrypt(plaintext_bytes)
return ciphertext
def decrypt_message(ciphertext, key, initialization_vector):
if (len(ciphertext) % 16) != 0:
print("Cipher has not the correct length, this was not encrypted by us.")
#return
cipher = AES.new(key, AES.MODE_CBC, initialization_vector)
plaintext = cipher.decrypt(ciphertext)
return plaintext
# create key and initialization vector
secret_key = b"_fl{CR-mCpaxyep}" # must be 16 bytes
secret_initialization_vector = secret_key
print(encrypt_message("aaaaaaaaaaaaaaaa", secret_key, secret_initialization_vector))
ZnJvbSBDcnlwdG8uQ2lwaGVyIGltcG9ydCBBRVMgIyBBRVMgY3J5cHRvCmZyb20gQ3J5cHRvLlJhbmRvbSBpbXBvcnQgZ2V0X3JhbmRvbV9ieXRlcwoKZGVmIGFkZF9wYWRkaW5nKG1zZyk6CiAgICBpZiBsZW4obXNnKSAlIDE2ICE9IDA6CiAgICAgICAgIyBtZXNzYWdlIGxlbmd0aCBtdXN0IGJlIGEgZmFjdG9yIG9mIDE2ISEhCiAgICAgICAgbmJfb2ZfY2hhcnNfdG9fcGFkID0gIDE2IC0gKGxlbihtc2cpICUgMTYpCiAgICAgICAgcGFkZGVkX21zZyA9IG1zZyArICgiICIgKiBuYl9vZl9jaGFyc190b19wYWQpCiAgICAgICAgcmV0dXJuIHBhZGRlZF9tc2cKICAgICMgbWVzc2FnZSBsZW5ndGggaXMgYWxyZWFkeSBhIGZhY3RvciBvZiAxNgogICAgcmV0dXJuIG1zZwoKZGVmIGVuY3J5cHRfbWVzc2FnZShwbGFpbnRleHQsIGtleSwgaW5pdGlhbGl6YXRpb25fdmVjdG9yKToKICAgICMgcGFkIHRoZSBtc2cgaWYgbmVjZXNzYXJ5CiAgICBwbGFpbnRleHQgPSBhZGRfcGFkZGluZyhwbGFpbnRleHQpCiAgICBwbGFpbnRleHRfYnl0ZXMgPSBwbGFpbnRleHQuZW5jb2RlKCJ1dGZfOCIpCiAgICAjIGNyZWF0ZSBhIG5ldyBBRVMgY3lwaGVyLiBBRVMgaGFzbid0IGJlZW4gYnJva2VuIHlldCwgc28gd2UncmUgc2FmZSBhcyBsb25nIGFzIG5vIG9uZSBrbm93cyBvdXIga2V5IQogICAgIyB3ZSB1c2UgQ0JDIG1vZGUsIHNvIHdlIG5lZWQgYW4gaW5pdGlhbGl6YXRpb24gdmVjdG9yLgogICAgY2lwaGVyID0gQUVTLm5ldyhrZXksIEFFUy5NT0RFX0NCQywgaW5pdGlhbGl6YXRpb25fdmVjdG9yKQogICAgY2lwaGVydGV4dCA9IGNpcGhlci5lbmNyeXB0KHBsYWludGV4dF9ieXRlcykKICAgIHJldHVybiBjaXBoZXJ0ZXh0CgoKCmRlZiBkZWNyeXB0X21lc3NhZ2UoY2lwaGVydGV4dCwga2V5LCBpbml0aWFsaXphdGlvbl92ZWN0b3IpOgogICAgaWYgKGxlbihjaXBoZXJ0ZXh0KSAlIDE2KSAhPSAwOgogICAgICAgIHByaW50KCJDaXBoZXIgaGFzIG5vdCB0aGUgY29ycmVjdCBsZW5ndGgsIHRoaXMgd2FzIG5vdCBlbmNyeXB0ZWQgYnkgdXMuIikKICAgICAgICAjcmV0dXJuCiAgICBjaXBoZXIgPSBBRVMubmV3KGtleSwgQUVTLk1PREVfQ0JDLCBpbml0aWFsaXphdGlvbl92ZWN0b3IpCiAgICBwbGFpbnRleHQgPSBjaXBoZXIuZGVjcnlwdChjaXBoZXJ0ZXh0KQogICAgcmV0dXJuIHBsYWludGV4dAogICAgCiMgY3JlYXRlIGtleSBhbmQgaW5pdGlhbGl6YXRpb24gdmVjdG9yCnNlY3JldF9rZXkgPSBiIl9mbHtDUi1tQ3BheHllcH0iICMgbXVzdCBiZSAxNiBieXRlcwpzZWNyZXRfaW5pdGlhbGl6YXRpb25fdmVjdG9yID0gc2VjcmV0X2tleQoKcHJpbnQoZW5jcnlwdF9tZXNzYWdlKCJhYWFhYWFhYWFhYWFhYWFhIiwgc2VjcmV0X2tleSwgc2VjcmV0X2luaXRpYWxpemF0aW9uX3ZlY3Rvcikp