Advertisement
justinooo

Python AES-256-CBC w/ PKCS7

Jul 26th, 2019
527
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 1.98 KB | None | 0 0
  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')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement