2009-05-21 14:49:12 -04:00
|
|
|
try:
|
|
|
|
import Crypto.Hash.SHA256
|
|
|
|
import Crypto.Cipher.AES
|
|
|
|
has_aes = True
|
|
|
|
except:
|
|
|
|
has_aes = False
|
2007-03-06 10:05:38 -05:00
|
|
|
|
2009-07-23 16:26:59 -04:00
|
|
|
class CrypterInitError(Exception):
|
|
|
|
pass
|
|
|
|
|
2009-05-21 10:24:29 -04:00
|
|
|
class Crypter(object):
|
2009-07-23 16:26:59 -04:00
|
|
|
'''Wraps AES functionality provided by pycrypto'''
|
|
|
|
def __init__(self, password, salt='aes.py', alignment=16):
|
|
|
|
'''Initializes a crypter object'''
|
2009-05-21 14:49:12 -04:00
|
|
|
if not has_aes:
|
2009-07-23 16:26:59 -04:00
|
|
|
raise CrypterInitError("pycrypto not installed")
|
|
|
|
self.password = password
|
|
|
|
self.salt = salt
|
|
|
|
self.hash = Crypto.Hash.SHA256.new(password + salt)
|
|
|
|
self.cipher = Crypto.Cipher.AES.new(self.hash.digest())
|
|
|
|
self.alignment = alignment
|
2009-05-21 10:24:29 -04:00
|
|
|
|
|
|
|
def pad(self, s):
|
2009-07-23 16:26:59 -04:00
|
|
|
'''Add NULL padding to create aligned data'''
|
|
|
|
xtra = len(s) % self.alignment
|
2009-05-21 10:24:29 -04:00
|
|
|
if xtra:
|
2009-07-23 16:26:59 -04:00
|
|
|
return s + '\x00' * (self.alignment - xtra)
|
2007-03-06 10:05:38 -05:00
|
|
|
else:
|
2009-05-21 10:24:29 -04:00
|
|
|
return s
|
|
|
|
|
|
|
|
def unpad(self, s):
|
2009-07-23 16:26:59 -04:00
|
|
|
'''Remove NULL padding to restore original data'''
|
2009-05-21 10:24:29 -04:00
|
|
|
l = len(s)
|
|
|
|
while l > 0 and s[l - 1] == '\x00':
|
|
|
|
l -= 1
|
|
|
|
return s[:l]
|
|
|
|
|
|
|
|
def encrypt(self, data):
|
2009-07-23 16:26:59 -04:00
|
|
|
'''Creates encrypted data string from original input'''
|
2009-05-21 10:24:29 -04:00
|
|
|
return self.cipher.encrypt(self.pad(data))
|
|
|
|
|
|
|
|
def decrypt(self, data):
|
2009-07-23 16:26:59 -04:00
|
|
|
'''Creates original data string from encrypted input'''
|
2009-05-21 10:24:29 -04:00
|
|
|
return self.unpad(self.cipher.decrypt(self.pad(data)))
|