Skip to content

Instantly share code, notes, and snippets.

@jathanism
Created November 9, 2012 00:33
Show Gist options
  • Save jathanism/4042921 to your computer and use it in GitHub Desktop.
Save jathanism/4042921 to your computer and use it in GitHub Desktop.
Simple AES crypto thingy to to encrypt/decrypt passwords.
# -*- coding: utf-8 -*-
"""
Simple AES crypto thingy to to encrypt/decrypt passwords.
"""
from Crypto.Cipher import AES # http://pypi.python.org/pypi/pycrypto
DEFAULT_PADDER = '\x03'
DEFAULT_KEYLEN = 16
KEY_LENGTHS = (16, 24, 32)
class Password(object):
"""
AES (Advanced Encryption Standard)` is a symmetric block cipher
standardized by NIST. It has a fixed data block size of 16 bytes. Its keys
can be 128, 192, or 256 bits long.
AES is very fast and secure, and it is the de facto standard for symmetric
encryption.
:param password:
The password string
:param passphrase:
The secret key. It must be 16 (AES-128), 24 (AES-192), or 32 (AES-256)
bytes long.
:param padder:
The padding character to use
:param keylen:
The expected length of the secret key
"""
def __init__(self, password, passphrase=None, padder=DEFAULT_PADDER,
keylen=DEFAULT_KEYLEN):
self.password = password
self.keylen = int(keylen)
if keylen not in KEY_LENGTHS:
raise SyntaxError("Keylen must be one of %r" % KEY_LENGTHS)
if passphrase is None or len(passphrase) < keylen:
raise SyntaxError("You must provide a %s-character passphrase" %
keylen)
self.passphrase = passphrase
self.aes = AES.new(self.passphrase)
self.padder = padder
self.encrypted_password = self.encrypt(self.password, commit=True)
def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self.password)
def pad_password(self, password, padder=None, keylen=None):
"""Pad the password to prepare for encryption"""
if padder is None:
padder = self.padder
if keylen is None:
keylen = self.keylen
padded_password = password
passlen = len(password)
if passlen < keylen:
padded_password += padder * (keylen - passlen)
return padded_password
def unpad_password(self, password=None, padder=None):
"""Unpad the password to prepare for use"""
if password is None:
password = self.password
if padder is None:
padder = self.padder
return password.replace(padder, '')
def encrypt(self, raw_password=None, commit=False):
"""Encrypt the password"""
if raw_password is None:
raw_password = self.password
password = self.pad_password(raw_password)
encrypted_password = self.aes.encrypt(password)
if commit:
self.encrypted_password = encrypted_password
return encrypted_password
def decrypt(self, encrypted_password=None):
"""Decrypt the password"""
if encrypted_password is None:
encrypted_password = self.encrypted_password
padded_password = self.aes.decrypt(encrypted_password)
return self.unpad_password(padded_password)
if __name__ == '__main__':
password = 'abc123'
passphrase = 'sever found defs' # Must be 16 chars
p = Password(password, passphrase)
e = p.encrypt()
print 'encrypted: %r' % e
print 'hexdigest:', e.encode('hex')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment