Skip to content

Instantly share code, notes, and snippets.

@aristofor
Created July 8, 2012 07:06
Show Gist options
  • Save aristofor/3069737 to your computer and use it in GitHub Desktop.
Save aristofor/3069737 to your computer and use it in GitHub Desktop.
Raccourcis AES-CBC +padding
# coding: utf-8
u"""
Raccourcis AES-CBC avec padding
Résumé:
>>> key = 'mon_petit_secret' # longueur 16, 24 ou 32 (v. ci après)
>>> clear = 'texte clair'
>>> crypt = encrypt(key, clear) # crypt : texte crypté, bytearray
'\xd1w=\xe7{\xd1v&q\xcc{lJIq\xf7\xad2-\x05u\x03\xf4\xc0ls\x04>\xaf\x9caq'
>>> decrypt(key, crypt)
'texte clair'
>>> crypt_text = b64encrypt(key, clear) # texte crypté ( encodé b64 )
'C43m9cr8cCok6Os1QHsz/tWZnPkU768cnhlVwLxC8yY='
>>> b64decrypt(key, crypt_text) # réciproque
'texte clair'
>>> decrypt('mauvais mot de p', crypt) # mauvaise clé
''
À méditer avant d'utiliser ces fonctions:
Un texte décrypté par une clé erronée et un texte de longeur nulle
correctement décrypté donneront le même résultat.
Extrait de la doc AES:
The secret key to use in the symmetric cipher.
It must be 16 (*AES-128*), 24 (*AES-192*), or 32 (*AES-256*) bytes long.
Structure utilisée pour CBC:
init vector + crypt( clear data + pad bytes + pad size )
initial vector:
len(iv) : 16 , toujours
"""
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
"""
taille des blocs, multiple de 16
ici la rep de pad_size permet block_size jusqu'à 256
"""
block_size = AES.block_size
""" taille de padding, rep de pad_size comprise """
pad_size = lambda s : block_size - (1+len(s)) % block_size
""" bourrage de zéros """
padding_zero = lambda s : ''.join(['\0' for x in xrange(pad_size(s))]+[chr(x)])
""" bourrage de randons """
padding_random = lambda s : (lambda x: ''.join([x and get_random_bytes(x)] +[chr(x-1)]))(pad_size(s))
padding = padding_random
""" crypte un bytearray """
do_encrypt = lambda key, clear, iv: iv + AES.new(key, AES.MODE_CBC, iv).encrypt(clear + padding(clear))
""" crée un iv et crypte un bytearray """
encrypt = lambda key, clear: do_encrypt(key,clear,get_random_bytes(16))
""" retrait du padding """
cutoff = lambda s : s[:-2-ord(s[-1])]
""" extrait un iv en tête et décrypte fin du bytearray """
do_decrypt = lambda key, crypt: AES.new(key, AES.MODE_CBC, crypt[:16]).decrypt(crypt[16:])
""" décrypte un bytearray """
decrypt = lambda key, crypt: cutoff( do_decrypt(key, crypt) )
""" raccourcis base64 """
import base64
b64encrypt = lambda key, clear: base64.b64encode(encrypt(key, clear))
b64decrypt = lambda key, crypt: decrypt(key, base64.b64decode(crypt))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment