Hãy để tôi giải quyết câu hỏi của bạn về "chế độ." AES256 là một loại mật mã khối. Nó lấy đầu vào một khóa 32 byte và chuỗi 16 byte, được gọi là khối và xuất ra một khối. Chúng tôi sử dụng AES trong một chế độ hoạt động để mã hóa. Các giải pháp ở trên đề xuất sử dụng CBC, đó là một ví dụ. Một cái khác được gọi là CTR, và nó có phần dễ sử dụng hơn:block cipher. It takes as input a 32-byte key and a 16-byte string, called the block and outputs a block. We use AES in a mode of operation in order to encrypt. The solutions above suggest using CBC, which is one example. Another is called CTR, and it's somewhat easier to use: Show
Điều này thường được gọi là AES-CTR. Tôi sẽ tư vấn thận trọng khi sử dụng AES-CBC với Pycrypto. Lý do là nó yêu cầu bạn chỉ định sơ đồ đệm, như được minh họa bằng các giải pháp khác được đưa ra. Nói chung, nếu bạn không cẩn thận về phần đệm, có những cuộc tấn công hoàn toàn phá vỡ mã hóa!I would advise caution in using AES-CBC with PyCrypto. The reason is that it requires you to specify the padding scheme, as exemplified by the other solutions given. In general, if you're not very careful about the padding, there are attacks that completely break encryption! Bây giờ, điều quan trọng cần lưu ý là khóa phải là chuỗi 32 byte ngẫu nhiên; Mật khẩu không đủ. Thông thường, khóa được tạo như SO:random, 32-byte string; a password does not suffice. Normally, the key is generated like so:
Một khóa cũng có thể được lấy từ mật khẩu:derived from a password, too:
Một số giải pháp ở trên đề xuất sử dụng SHA256 để lấy chìa khóa, nhưng điều này thường được coi là thực hành mật mã xấu. Kiểm tra Wikipedia để biết thêm về các chế độ hoạt động. Hãy minh họa các khái niệm giải mã AES và giải mã AES thông qua mã nguồn làm việc trong Python.AES encryption and AES decryption concepts through working source code in Python. Ví dụ đầu tiên dưới đây sẽ minh họa một mã hóa AES dựa trên mật khẩu đơn giản (PBKDF2 + AES-CTR) mà không cần xác thực tin nhắn (mã hóa không xác thực). Ví dụ tiếp theo sẽ thêm xác thực tin nhắn (sử dụng chế độ AES-GCM), sau đó sẽ thêm mật khẩu vào dẫn xuất khóa (AES-256-GCM + Scrypt).password-based AES encryption (PBKDF2 + AES-CTR) without message authentication (unauthenticated encryption). The next example will add message authentication (using the AES-GCM mode), then will add password to key derivation (AES-256-GCM + Scrypt). Hãy bắt đầu với AES-256-CTR đơn giản mã hóa không xác thực. Cài đặt Thư viện Python pyaes và pbkdf2pyaes and pbkdf2Đầu tiên, cài đặt Thư viện Python Tiếp theo, cài đặt Thư viện Python Bây giờ, hãy chơi với một ví dụ mã hóa / giải mã AES đơn giản. Mật khẩu cho dẫn xuất khóaĐầu tiên bắt đầu bằng cách dẫn xuất khóa: Từ mật khẩu đến khóa mã hóa 256 bit.key derivation: from password to 256-bit encryption key. Nhập PYAES, PBKDF2, Binascii, OS, Bí mật pyaes, pbkdf2, binascii, os, secrets # Xuất phát khóa mã hóa AES 256 bit từ mật khẩu Mật khẩuSalt = OS.urandom (16)= os.urandom(16) key = pbkdf2.pbkdf2 (mật khẩu, passwordsalt) .read (32)= pbkdf2.PBKDF2(password, passwordSalt).read(32) in ('Khóa mã hóa AES:', Binascii.hexlify (khóa))('AES encryption key:', binascii.hexlify(key)) Mã trên có được khóa 256 bit bằng thuật toán dẫn xuất khóa PBKDF2 từ mật khẩu Đầu ra từ mã trên có thể trông như thế này: Khóa mã hóa AES: B'7625E224DC0F0EC91AD28C1EE67B1EB96D1A5459533C5C950F44AAE1E32F2DA3 ' Key có nguồn gốc bao gồm 64 chữ số hex (32 byte), đại diện cho số nguyên 256 bit. Nó sẽ khác nếu bạn chạy mã trên nhiều lần, bởi vì một muối ngẫu nhiên được sử dụng mọi lúc. Nếu bạn sử dụng cùng một loại muối, cùng một khóa sẽ được bắt nguồn.key consists of 64 hex digits (32 bytes), which represents a 256-bit integer number. It will be different if you run the above code several times, because a random salt is used every time. If you use the same salt, the same key will be derived. Mã hóa AES (Chế độ khối CTR)Tiếp theo, tạo một vectơ ban đầu (iv) ngẫu nhiên 256 bit cho chế độ khối CTR AES và thực hiện mã hóa AES-256-CTR:random 256-bit initial vector (IV) for the AES CTR block mode and perform the AES-256-CTR encryption: # Mã hóa bản rõ bằng khóa đã cho: # CIPHERTEXT = AES-256-CTR-Encrypt (Pufftext, Key, IV) IV = Secrets.randbits (256)= secrets.randbits(256) plaintext = "Text for incryption"="Text for encryption" AES = PYAES.AESModeOfoperationCtr (Key, Pyaes.Count (IV))= pyaes.AESModeOfOperationCTR(key, pyaes.Counter(iv)) CIPHERTEXT = AES.Encrypt (Pufftext)= aes.encrypt(plaintext) in ('được mã hóa:', Binascii.hexlify (Ciphertext)))('Encrypted:', binascii.hexlify(ciphertext)) Đầu ra từ mã trên có thể trông như thế này: Khóa mã hóa AES: B'7625E224DC0F0EC91AD28C1EE67B1EB96D1A5459533C5C950F44AAE1E32F2DA3 ' Key có nguồn gốc bao gồm 64 chữ số hex (32 byte), đại diện cho số nguyên 256 bit. Nó sẽ khác nếu bạn chạy mã trên nhiều lần, bởi vì một muối ngẫu nhiên được sử dụng mọi lúc. Nếu bạn sử dụng cùng một loại muối, cùng một khóa sẽ được bắt nguồn.ciphertext consists of 38 hex digits (19 bytes, 152 bits). This is the size of the input data, the message
Mã hóa AES (Chế độ khối CTR)initial vector (IV) should be stored along with the ciphertext, because without it, the decryption will be impossible. The IV should be randomly generated for each AES encryption (not hard-coded) for higher security. Tiếp theo, tạo một vectơ ban đầu (iv) ngẫu nhiên 256 bit cho chế độ khối CTR AES và thực hiện mã hóa AES-256-CTR:plaintext with the same encryption key several times, the output will be different every time, due to the randomness in the IV. This is intended behavior and it increases the security, e.g. resistance to dictionary attacks. # Mã hóa bản rõ bằng khóa đã cho:# CIPHERTEXT = AES-256-CTR-Encrypt (Pufftext, Key, IV)decrypt a ciphertext using the AES-CTR-256 algorithm. The input consists of ciphertext + encryption key + the IV for the CTR counter. The output is the original plaintext. The code is pretty simple: IV = Secrets.randbits (256) plaintext = "Text for incryption" AES = PYAES.AESModeOfoperationCtr (Key, Pyaes.Count (IV))= pyaes.AESModeOfOperationCTR(key, pyaes.Counter(iv)) CIPHERTEXT = AES.Encrypt (Pufftext)= aes.decrypt(ciphertext) in ('đã giải mã:', được giải mã)('Decrypted:', decrypted) Đầu ra của những điều trên nên như thế này: Đã được giải mã: b'text để mã hóa ' Lưu ý rằng đối tượng Cũng lưu ý rằng mã trên không thể phát hiện khóa sai, bản quyền sai hoặc sai IV. Nếu bạn sử dụng một khóa không chính xác để giải mã mật mã, bạn sẽ nhận được một văn bản không thể đọc sai. Điều này có thể thấy rõ bằng mã bên dưới:cannot detect wrong key, wrong ciphertext or wrong IV. If you use an incorrect key to decrypt the ciphertext, you will get a wrong unreadable text. This is clearly visible by the code below: key = os.urandom (32)# phím giải mã ngẫu nhiên= os.urandom(32) # random decryption key AES = PYAES.AESModeOfoperationCtr (Key, Pyaes.Count (IV))= pyaes.AESModeOfOperationCTR(key, pyaes.Counter(iv)) in ('bị giải mã sai:', aes.decrypt (bản mã)))('Wrongly decrypted:', aes.decrypt(ciphertext)) Đầu ra của nỗ lực giải mã không chính xác ở trên có thể như thế này: Đã giải mã sai: B '\ XE6! Bây giờ là thời gian của bạn để chơi với ví dụ mã trên. Cố gắng mã hóa và giải mã các thông báo khác nhau, để thay đổi thông báo đầu vào, kích thước khóa, mã cứng IV, khóa và các tham số khác, chuyển sang chế độ CBC và xem kết quả thay đổi như thế nào. Thích học bằng cách chơi.play with the above code example. Try to to encrypt and decrypt different messages, to change the input message, the key size, to hard-code the IV, the key and other parameters, switch to CBC mode, and see how the results change. Enjoy learning by playing. Bây giờ, hãy đưa ra một ví dụ đầy đủ về cách sử dụng cấu trúc mã hóa đối xứng AES-256-GCM. Chúng tôi sẽ sử dụng một thư viện Python khác cho AES, được gọi là Tiếp theo, chúng ta hãy chơi với ví dụ AES-GCM dưới đây trong Python, tạo ra khóa mã hóa ngẫu nhiên (khóa bí mật) và sử dụng nó để mã hóa một tin nhắn văn bản, sau đó giải mã nó trở lại thông báo bản rõ gốc:AES-GCM example in Python, which generates a random encryption key (secret key) and uses it to encrypt a text message, then decrypts it back to the original plaintext message: từ tiền điện tử. Nhập AES Crypto.Cipher import AES DefenCrypt_AES_GCM (MSG, SecretKey): encrypt_AES_GCM(msg, secretKey): AESCIPHER = AES.new (SecretKey, AES.Mode_GCM)= AES.new(secretKey, AES.MODE_GCM) Ciphertext, AuthTag = AESCIPHER.ENCRYPT_AND_DIGEST (MSG), authTag = aesCipher.encrypt_and_digest(msg) Return (Bản mã, AESCIPHER.Nonce, AuthTag) (ciphertext, aesCipher.nonce, authTag) DefDecrypt_AES_GCM (EncryptedMSG, SecretKey): decrypt_AES_GCM(encryptedMsg, secretKey): .ciphertext, nonce, authTag) = encryptedMsg AESCIPHER = AES.new (SecretKey, AES.Mode_GCM, Nonce)= AES.new(secretKey, AES.MODE_GCM, nonce) PlainText = AESCIPHER.DECRYPT_AND_VERIFY (CIPHERTEXT, AUTHTAG)= aesCipher.decrypt_and_verify(ciphertext, authTag) SecretKey = Os.urandom (32)# 256-bit Khóa mã hóa ngẫu nhiên= os.urandom(32)# 256-bit random encryption key in ("Khóa mã hóa:", Binascii.hexlify (SecretKey))("Encryption key:", binascii.hexlify(secretKey)) MSG = B'message cho AES-256-GCM + mã hóa Scrypt '=b'Message for AES-256-GCM + Scrypt encryption' encryptedMSG = encrypt_aes_gcm (msg, secretkey)= encrypt_AES_GCM(msg, secretKey) 'Ciphertext': Binascii.hexlify (EncryptedMSG [0]),: binascii.hexlify(encryptedMsg[0]), 'Aesiv': Binascii.Hexlify (EncryptedMSG [1]),: binascii.hexlify(encryptedMsg[1]), 'authtag': Binascii.hexlify (EncryptedMSG [2]): binascii.hexlify(encryptedMsg[2]) decryptedMsg = decrypt_aes_gcm (encryptedMSG, secretKey)= decrypt_AES_GCM(encryptedMsg, secretKey) in ("DePryptedMSG", DecryptedMSG)("decryptedMsg", decryptedMsg) Mã hóa AES-GCM lấy phím thông báo + mã mã hóa và tạo dưới dạng đầu ra một tập hợp các giá trị: {Ciphertext + nonce + authtag}.message + encryption key and produces as output a set of values: { ciphertext + nonce + authTag }.
Kích thước khóa mã hóa được tạo trong mã trên là 256 bit (32 byte) và nó cấu hình mật mã AES-GCM dưới dạng AES-256-GCM. Nếu chúng ta thay đổi kích thước chính thành 128 bit hoặc 192 bit, chúng ta sẽ sử dụng AES-128-GCM hoặc AES-192-GCM tương ứng.key size generated in the above code is 256 bits (32 bytes) and it configures the AES-GCM cipher as AES-256-GCM. If we change the key size to 128 bits or 192 bits, we shall use AES-128-GCM or AES-192-GCM respectively. Đầu ra từ mã trên trông như thế này: Khóa mã hóa: B'233F8CE4AC6AA125927CCD98AF5750D08C9C61D98A3F5D43CBF096B4CAAEBE80 ' encryptedMsg {'ciphertext': b'1334cd5d487f7f47924187c94424a2079656838e063e5521e7779e441aa513de268550a89917fbfb0492fc', 'aesIV': b'2f3849399c60cb04b923bd33265b81c7', 'authTag': b'af453a410d142bc6f926c0f3bc776390'} DecryptedMSG b'message cho AES-256-GCM + mã hóa Scrypt ' Có thể thấy rằng khóa mã hóa ở trên là 256 bit (64 chữ số hex), bản mã có độ dài tương đương với thông báo đầu vào (43 byte), IV là 128 bit (32 chữ số hex) và thẻ xác thực là 128 bit ( 32 chữ số hex). Nếu chúng ta thay đổi một cái gì đó trước khi giải mã (ví dụ: bản mã của IV), chúng ta sẽ có được và ngoại lệ, vì tính toàn vẹn của thông báo sẽ bị phá vỡ:encryption key above is 256 bits (64 hex digits), the ciphertext has the same length as the input message (43 bytes), the IV is 128 bits (32 hex digits) and the authentication tag is 128 bits (32 hex digits). If we change something before the decryption (e.g. the ciphertext of the IV), we will get and exception, because the message integrity will be broken: EncryptedMsg = (B'Wrong Chimhertext ', EncryptedMSG [1], EncryptedMSG [2])= (b'wrong chiphertext', encryptedMsg[1], encryptedMsg[2]) decryptedMSG = decrypt_aes_gcm (encryptedMSG, secretKey)# valueError: MAC séc không thành công= decrypt_AES_GCM(encryptedMsg, secretKey)# ValueError: MAC check failed Ví dụ AES-256-GCM + ScryptBây giờ chúng ta hãy đưa ra một ví dụ phức tạp hơn: Mã hóa văn bản AES bằng mật khẩu văn bản. Chúng tôi sẽ sử dụng cấu trúc mã hóa được xác thực AES-256-GCM, kết hợp với dẫn xuất khóa Scrypt:AES encryption of text by text password. We shall use the authenticated encryption construction AES-256-GCM, combined with Scrypt key derivation: từ tiền điện tử. Nhập AES Crypto.Cipher import AES DefenCrypt_AES_GCM (MSG, SecretKey): scrypt, os, binascii AESCIPHER = AES.new (SecretKey, AES.Mode_GCM) encrypt_AES_GCM(msg, password): Ciphertext, AuthTag = AESCIPHER.ENCRYPT_AND_DIGEST (MSG)= scrypt.hash(password, kdfSalt, N=16384, r=8, p=1, buflen=32) AESCIPHER = AES.new (SecretKey, AES.Mode_GCM)= AES.new(secretKey, AES.MODE_GCM) Ciphertext, AuthTag = AESCIPHER.ENCRYPT_AND_DIGEST (MSG), authTag = aesCipher.encrypt_and_digest(msg) Return (Bản mã, AESCIPHER.Nonce, AuthTag)(kdfSalt, ciphertext, aesCipher.nonce, authTag) DefDecrypt_AES_GCM (EncryptedMSG, SecretKey): decrypt_AES_GCM(encryptedMsg, password): .kdfSalt, ciphertext, nonce, authTag)= encryptedMsg Ciphertext, AuthTag = AESCIPHER.ENCRYPT_AND_DIGEST (MSG)= scrypt.hash(password, kdfSalt, N=16384, r=8, p=1, buflen=32) AESCIPHER = AES.new (SecretKey, AES.Mode_GCM, Nonce)= AES.new(secretKey, AES.MODE_GCM, nonce) PlainText = AESCIPHER.DECRYPT_AND_VERIFY (CIPHERTEXT, AUTHTAG)= aesCipher.decrypt_and_verify(ciphertext, authTag) MSG = B'message cho AES-256-GCM + mã hóa Scrypt '=b'Message for AES-256-GCM + Scrypt encryption' Mật khẩu = B'S3KR3TP4SSW0RD '=b's3kr3tp4ssw0rd' encryptedMSG = encrypt_aes_gcm (tin nhắn, mật khẩu)= encrypt_AES_GCM(msg, password) 'Kdfsalt': Binascii.Hexlify (EncryptedMSG [0]),: binascii.hexlify(encryptedMsg[0]), 'Ciphertext': Binascii.hexlify (EncryptedMSG [1]),: binascii.hexlify(encryptedMsg[1]), 'Aesiv': Binascii.Hexlify (EncryptedMSG [2]),: binascii.hexlify(encryptedMsg[2]), 'authtag': Binascii.hexlify (EncryptedMSG [3]): binascii.hexlify(encryptedMsg[3]) decryptedMsg = decrypt_aes_gcm (encryptedMSG, password)= decrypt_AES_GCM(encryptedMsg, password) in ("DePryptedMSG", DecryptedMSG)("decryptedMsg", decryptedMsg) Mã trên được mã hóa bằng tin nhắn văn bản AES-256-GCM được cho bằng mật khẩu văn bản.AES-256-GCM given text message by given text password.
Đầu ra từ mã trên trông như thế này:output from the above code looks like this:
encryptedMsg {'kdfSalt': b'2dd0b783290747ba62a63fc53591170d', 'ciphertext': b'223ed888dcd216dcd40c47ff7cdaa7fd7eab65f4f0405350a43c5cad5b6b47b527c709edec29d7d6967518', 'aesIV': b'7f114d946c77508ed2e6afe652c78f21', 'authTag': b'e84a14b9542320a0b1473141c989c48f'} DecryptedMSG b'message cho AES-256-GCM + mã hóa Scrypt ' Nếu bạn chạy cùng một mã, đầu ra sẽ khác nhau, do tính ngẫu nhiên (muối KDF ngẫu nhiên + AES nonce ngẫu nhiên). Mã hóa AES được thực hiện như thế nào?Thuật toán mã hóa AES (còn được gọi là thuật toán Rijndael) là một thuật toán mật mã khối đối xứng với kích thước khối/chunk là 128 bit.Nó chuyển đổi các khối riêng lẻ này bằng cách sử dụng các khóa 128, 192 và 256 bit. Khi nó mã hóa các khối này, nó kết hợp chúng lại với nhau để tạo thành bản mã.It converts these individual blocks using keys of 128, 192, and 256 bits. Once it encrypts these blocks, it joins them together to form the ciphertext.
Thư viện nào có thể cung cấp AES cho Python?Cài đặt pycrypto Như đã đề cập, chúng tôi sẽ sử dụng thư viện pycrypto để mã hóa và giải mã dữ liệu bằng AES.Cách dễ nhất để cài đặt nó là sử dụng PIP, Trình quản lý gói Python.Hướng dẫn này đã được thử nghiệm trên Python 2.7.pycrypto
As mentioned, we will use the pycrypto library to encrypt and decrypt the data with AES. The easiest way to install it is using pip, a Python package manager. This tutorial was tested on Python 2.7. |