justinooo

Python AES-256-CBC w/ PKCS7

Jul 26th, 2019
136
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import base64
  2. import hashlib
  3. from Crypto import Random
  4. from Crypto.Cipher import AES
  5. from Crypto.Protocol import KDF
  6. from Crypto.Util.Padding import pad, unpad
  7.  
  8.  
  9. ### AES-256-CBC w/ PKCS7 padding ###
  10.  
  11. # 0x28, 0x7c, 0x6a, 0xa2
  12. # 0x2e, 0xa6, 0x46, 0x4b
  13. # 0x68, 0xef, 0x91, 0xec
  14. # 0x0e, 0x8c, 0x3e, 0x50
  15. salt_bytes = [0x28, 0x7c, 0x6a, 0xa2, 0x2e, 0xa6, 0x46, 0x4b, 0x68, 0xef, 0x91, 0xec, 0x0e, 0x8c, 0x3e, 0x50]
  16. salt = "".join(map(chr, salt_bytes))
  17.  
  18. # for debugging purposes
  19. def print_bytes(bytes):
  20.     count = len(bytes)
  21.     for i in range(count):
  22.         byte = bytes[i]
  23.         last = i == count - 1
  24.         print(hex(byte), end = "")
  25.         print("\n" if last else ", ", end = "")
  26.  
  27. key_size = 32 # 256 bits
  28.  
  29. def encrypt_string(plain, key):
  30.  
  31.     # use PBKDF2 key derivation
  32.     # RFC 2898: https://www.ietf.org/rfc/rfc2898.txt
  33.     key = KDF.PBKDF2(key, salt, key_size)
  34.  
  35.     # pad text with PKCS7
  36.     # RFC 2315: https://tools.ietf.org/html/rfc2315
  37.     padded = pad(plain.encode(), AES.block_size, 'pkcs7')
  38.  
  39.     # generate random iv
  40.     iv = Random.new().read(AES.block_size)
  41.  
  42.     # create cipher and encrypt padded data
  43.     cipher = AES.new(key, AES.MODE_CBC, iv)
  44.     encrypted = cipher.encrypt(padded)
  45.  
  46.     # return encoded cipher text
  47.     # first 16 bytes = iv, rest is encrypted bytes
  48.     return base64.b64encode(iv + encrypted)
  49.  
  50. def decrypt_string(enc, key):
  51.  
  52.     # use PBKDF2 key derivation
  53.     # RFC 2898: https://www.ietf.org/rfc/rfc2898.txt
  54.     key = KDF.PBKDF2(key, salt, key_size)
  55.  
  56.     # decode cipher text and determine iv (first 16 bytes)
  57.     enc = base64.b64decode(enc)
  58.     iv = enc[:AES.block_size]
  59.  
  60.     # create cipher and decrypt encrypted bytes (skip first 16 bytes)
  61.     cipher = AES.new(key, AES.MODE_CBC, iv)
  62.     decrypted = cipher.decrypt(enc[AES.block_size:])
  63.  
  64.     # unpad decrypted bytes
  65.     unpadded = unpad(decrypted, AES.block_size, 'pkcs7')
  66.  
  67.     # convert bytes to UTF-8 encoded string and return
  68.     return unpadded.decode('utf-8')
RAW Paste Data