Disclaimer: I understand that the following is not suited to give "security" in a production environment. It is simply meant as "a little bit better" than using XOR or rot13 on sensitive data that is stored on my system.
I put together the following code to allow me to use AES encryption for those sensitive values. AES requires 16 byte chunks; so I need padding. And I want to save that data in text files; so I added base64 encoding:
from __future__ import print_function
from Crypto.Cipher import AES
import base64
crypto = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
BS = 16
pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
unpad = lambda s: s[0:-ord(s[-1])]
def scramble(data):
return base64.b64encode(crypto.encrypt(pad(data)))
def unscramble(data):
return unpad(crypto.decrypt(base64.b64decode(data)))
incoming = "abc"
print("in: {}".format(incoming))
scrambled = scramble(incoming)
print("scrambled: {}".format(scrambled))
andback= unscramble(scrambled)
print("reversed : {}".format(andback))
For python2; that prints:
in: abc
scrambled: asEkqlUDiqlUpW1lw09UlQ==
reversed :
For python3; I run into
unpad = lambda s: s[0:-ord(s[-1])]
TypeError: ord() expected string of length 1, but int found
Two questions:
One problem with your code is that you are using the same cipher object for both encryption and decryption. This won't work, as the cipher objects are stateful:PyCrypto Documentation
You can create another object for decrypting, as in:
crypto2 = AES.new('This is a key123', AES.MODE_CBC, 'This is an IV456')
, and then use this object to decrypt.