Biarkan saya menjawab pertanyaan Anda tentang "mode." AES256 adalah sejenis cipher blok . Dibutuhkan sebagai input kunci 32-byte dan string 16-byte, yang disebut blok dan output blok. Kami menggunakan AES dalam mode operasi untuk mengenkripsi. Solusi di atas menyarankan menggunakan CBC, yang merupakan salah satu contoh. Lain disebut CTR, dan itu agak lebih mudah digunakan:
from Crypto.Cipher import AES
from Crypto.Util import Counter
from Crypto import Random
# AES supports multiple key sizes: 16 (AES128), 24 (AES192), or 32 (AES256).
key_bytes = 32
# Takes as input a 32-byte key and an arbitrary-length plaintext and returns a
# pair (iv, ciphtertext). "iv" stands for initialization vector.
def encrypt(key, plaintext):
assert len(key) == key_bytes
# Choose a random, 16-byte IV.
iv = Random.new().read(AES.block_size)
# Convert the IV to a Python integer.
iv_int = int(binascii.hexlify(iv), 16)
# Create a new Counter object with IV = iv_int.
ctr = Counter.new(AES.block_size * 8, initial_value=iv_int)
# Create AES-CTR cipher.
aes = AES.new(key, AES.MODE_CTR, counter=ctr)
# Encrypt and return IV and ciphertext.
ciphertext = aes.encrypt(plaintext)
return (iv, ciphertext)
# Takes as input a 32-byte key, a 16-byte IV, and a ciphertext, and outputs the
# corresponding plaintext.
def decrypt(key, iv, ciphertext):
assert len(key) == key_bytes
# Initialize counter for decryption. iv should be the same as the output of
# encrypt().
iv_int = int(iv.encode('hex'), 16)
ctr = Counter.new(AES.block_size * 8, initial_value=iv_int)
# Create AES-CTR cipher.
aes = AES.new(key, AES.MODE_CTR, counter=ctr)
# Decrypt and return the plaintext.
plaintext = aes.decrypt(ciphertext)
return plaintext
(iv, ciphertext) = encrypt(key, 'hella')
print decrypt(key, iv, ciphertext)
Ini sering disebut sebagai AES-CTR. Saya akan menyarankan agar berhati-hati dalam menggunakan AES-CBC dengan PyCrypto . Alasannya adalah itu mengharuskan Anda untuk menentukan skema padding , sebagaimana dicontohkan oleh solusi lain yang diberikan. Secara umum, jika Anda tidak terlalu berhati-hati dengan padding, ada serangan yang benar-benar merusak enkripsi!
Sekarang, penting untuk dicatat bahwa kunci tersebut harus berupa string 32 byte acak ; kata sandi tidak cukup. Biasanya, kunci dibuat seperti ini:
# Nominal way to generate a fresh key. This calls the system's random number
# generator (RNG).
key1 = Random.new().read(key_bytes)
Kunci juga dapat diturunkan dari kata sandi :
# It's also possible to derive a key from a password, but it's important that
# the password have high entropy, meaning difficult to predict.
password = "This is a rather weak password."
# For added # security, we add a "salt", which increases the entropy.
#
# In this example, we use the same RNG to produce the salt that we used to
# produce key1.
salt_bytes = 8
salt = Random.new().read(salt_bytes)
# Stands for "Password-based key derivation function 2"
key2 = PBKDF2(password, salt, key_bytes)
Beberapa solusi di atas menyarankan menggunakan SHA256 untuk mendapatkan kunci, tetapi ini umumnya dianggap praktik kriptografi yang buruk . Lihat wikipedia untuk informasi lebih lanjut tentang mode operasi.