AES can be susceptible to brute force when the encryption keys are generated by a password. In this case we cause an exception for an incorrect encryption key, or we create one which does not have plain text in the decrypted value.
AES Crack (Brute force on passwords) |
Example
The following uses a password of 'napier' and a secret word of 'edinburgh':
=========Calculation==================== Word: edinburgh Password: napier Key 5a6381be5d2e9bfdce1ea1a2801ae34685c908d14a729f5be23dfeddecef042d Cipher: 16b5d75e609c7b8fd100ef933bb15542 =========Calculation==================== Plain text is edinburgh and password is napier
Method
Although we use a 256-bit AES key, we are generating it from a password, so the number of keys possible is limited. In the following code we generate the keys for 'napier','test','password','foxtrot','123456' and 'qwerty', and try these. If the decryption process creates an exception or it unprintable, we ignore it.
Code
An outline of the code used is:
from Crypto.Cipher import AES import hashlib import sys import binascii import Padding word='edinburgh' passwords=['napier','test','password','foxtrot','123456','qwerty'] password='napier' passw='' if (len(sys.argv)>1): word=str(sys.argv[1]) if (len(sys.argv)>2): password=str(sys.argv[2]) plaintext='' def isprintable(s, codec='utf8'): try: s.decode(codec) except UnicodeDecodeError: return False else: return True def encrypt(plaintext,key, mode): encobj = AES.new(key,mode) return(encobj.encrypt(plaintext)) def decrypt(ciphertext,key, mode): encobj = AES.new(key,mode) return(encobj.decrypt(ciphertext)) ciphertext=[] key = hashlib.sha256(password.encode()).digest() print('\n=========Calculation====================') print('Word: ',word) print('Password: ',password) print('Key ',binascii.hexlify(key)) plaintext = Padding.appendPadding(word,blocksize=Padding.AES_blocksize,mode='CMS') ciphertext = ciphertext+ list(encrypt(plaintext.encode(),key,AES.MODE_ECB)) print('Cipher: ',binascii.hexlify(bytes(ciphertext))) print('\n=========Bruce Force====================') for passw in passwords: try: key = hashlib.sha256(passw.encode()).digest() plaintext = decrypt(bytes(ciphertext),key,AES.MODE_ECB) if (isprintable(plaintext)): p=Padding.removePadding(plaintext.decode(),mode='CMS') print('Plain text is ',p,' and password is ', passw) except: print('', end=' ')