Я пытаюсь зашифровать файл с помощью python, например:
import os
from binascii import hexlify
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
key = hexlify(os.urandom(16))
print(key.decode())
iv = hexlify(os.urandom(16))
print(iv[:16].decode())
cipher = Cipher(algorithms.AES(key), modes.CBC(iv[:16]))
encryptor = cipher.encryptor()
msg = b"a secret message"
ct = encryptor.update(msg) + encryptor.finalize()
open("ciphertext.bin", "wb").write(ct)
а затем я пытаюсь расшифровать его с помощью openSSL (мне нужно использовать openSSL, как это было запрошено моим профессором), чтобы проверить успех, например:
openssl enc -aes-128-cbc -d -K <key_the_program_prints> -iv <iv_the_program_prints> -in ciphertext.bin -out res.txt
но я получаю:
hex string is too short, padding with zero bytes to length
bad decrypt
139711335437696:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:crypto/evp/evp_enc.c:583:
Что я делаю не так? Я считаю, что у меня правильный размер во всех компонентах, поэтому я не понимаю ошибки
Это как-то связано с тем, что python обрабатывает ключ и iv в байтах, и я использую их в строковом формате для openSSL?
Спасибо
В коде Python ключ (16 байт для AES-128) и IV (16 байт для AES) должны передаваться в двоичном виде. В операторе OpenSSL они должны быть указаны в шестнадцатеричном кодировании, т.е. в коде Python используйте:
key = os.urandom(16)
print(hexlify(key)) # for OpenSSL
iv = os.urandom(16)
print(hexlify(iv)) # for OpenSSL
Это также означает, что iv
можно использовать напрямую вместо iv[:16]
во время создания экземпляра Cipher
.
Библиотека криптографии не заполняется автоматически. Однако OpenSSL применяет заполнение PKCS7 по умолчанию. Поэтому это необходимо отключить с помощью параметра -nopad в операторе OpenSSL, здесь.
Обратите внимание, что без заполнения могут быть зашифрованы только открытые тексты, длина которых является целым числом, кратным размеру блока AES (16 байт). В противном случае необходимо применить прокладку. Библиотека криптографии поддерживает несколько вариантов заполнения, в том числе PKCS7, здесь. Разумеется, при заполнении параметр -nopad в операторе OpenSSL должен быть удален.
Большое спасибо, вы спасли одно из моих заданий по прикладной криптографии! С Рождеством!