Created
November 9, 2012 00:33
-
-
Save jathanism/4042921 to your computer and use it in GitHub Desktop.
Simple AES crypto thingy to to encrypt/decrypt passwords.
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
# -*- 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