justinooo icon

Python AES-256-CBC w/ PKCS7

justinooo | PRO | 07/26/19 09:24:34 AM UTC | 0 ⭐ | 922 👁️ | Never ⏰ | []
Python |

1.98 KB

|

None

|

0 👍

/

0 👎

import base64
import hashlib
from Crypto import Random
from Crypto.Cipher import AES
from Crypto.Protocol import KDF
from Crypto.Util.Padding import pad, unpad
 
 
### AES-256-CBC w/ PKCS7 padding ###
 
# 0x28, 0x7c, 0x6a, 0xa2
# 0x2e, 0xa6, 0x46, 0x4b
# 0x68, 0xef, 0x91, 0xec
# 0x0e, 0x8c, 0x3e, 0x50
salt_bytes = [0x28, 0x7c, 0x6a, 0xa2, 0x2e, 0xa6, 0x46, 0x4b, 0x68, 0xef, 0x91, 0xec, 0x0e, 0x8c, 0x3e, 0x50]
salt = "".join(map(chr, salt_bytes))
 
# for debugging purposes
def print_bytes(bytes):
    count = len(bytes)
    for i in range(count):
        byte = bytes[i]
        last = i == count - 1
        print(hex(byte), end = "")
        print("\n" if last else ", ", end = "")
 
key_size = 32 # 256 bits
 
def encrypt_string(plain, key):
 
    # use PBKDF2 key derivation
    # RFC 2898: https://www.ietf.org/rfc/rfc2898.txt
    key = KDF.PBKDF2(key, salt, key_size)
 
    # pad text with PKCS7
    # RFC 2315: https://tools.ietf.org/html/rfc2315
    padded = pad(plain.encode(), AES.block_size, 'pkcs7')
 
    # generate random iv
    iv = Random.new().read(AES.block_size)
 
    # create cipher and encrypt padded data
    cipher = AES.new(key, AES.MODE_CBC, iv)
    encrypted = cipher.encrypt(padded)
 
    # return encoded cipher text
    # first 16 bytes = iv, rest is encrypted bytes
    return base64.b64encode(iv + encrypted)
 
def decrypt_string(enc, key):
 
    # use PBKDF2 key derivation
    # RFC 2898: https://www.ietf.org/rfc/rfc2898.txt
    key = KDF.PBKDF2(key, salt, key_size)
 
    # decode cipher text and determine iv (first 16 bytes)
    enc = base64.b64decode(enc)
    iv = enc[:AES.block_size]
 
    # create cipher and decrypt encrypted bytes (skip first 16 bytes)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = cipher.decrypt(enc[AES.block_size:])
 
    # unpad decrypted bytes
    unpadded = unpad(decrypted, AES.block_size, 'pkcs7')
 
    # convert bytes to UTF-8 encoded string and return
    return unpadded.decode('utf-8')

Comments