Сообщение об ошибке
Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).
Также выводится как
- ValueError: Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters). Details: ASN.1 parsing error: short data (needed at least 48 additional bytes)
- Could not deserialize key data. The data may be in an incorrect format, the provided password may be incorrect, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).
- ValueError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [<OpenSSLError(code=503841036, lib=60, reason=524556, reason_text=unsupported)>
Проверено на разных релизах: cryptography 45.0 и новее добавляет «Details: …» (например, «ASN.1 parsing error: short data»). Версии 43–44 выбрасывают текст в виде кортежа с объектами ошибок OpenSSL и добавляют в предложение «the provided password may be incorrect» (и выдают это сообщение также при неверном пароле); версии 36–42 выбрасывают вариант с кортежем без этой фразы.
Python cryptography — ValueError from load_pem_private_key / load_der_private_key / load_der_public_key
Что это означает
Библиотека cryptography нашла данные ключа, но не смогла превратить их в объект ключа. Для входных данных в формате PEM строки обрамления были в порядке (иначе вы увидели бы «Unable to load PEM file»), так что проблема в DER внутри: он обрезан, имеет не ту структуру, которую ожидает функция загрузки, или описывает ключ, который cryptography отказывается загружать, — EC-ключ с явными параметрами кривой или ключ, зашифрованный алгоритмом, который она не поддерживает. Новые версии добавляют «Details: …» с низкоуровневой причиной из ASN.1.
Почему это происходит
Тело в base64 неполное или изменено
частоСтрока, потерянная при копировании ключа из терминала или менеджера секретов, ключ, обрезанный полем с ограничением размера, или символы, изменённые редактором. Заголовок и завершающая строка остаются на месте, поэтому разбор PEM проходит успешно, а разбор DER — нет.
Функция загрузки не соответствует структуре ключа
частоОткрытый ключ, переданный в `load_der_private_key`, сертификат, переданный в функцию загрузки ключа, или ключ в формате OpenSSH (`-----BEGIN OPENSSH PRIVATE KEY-----`), переданный в `load_pem_private_key` вместо `load_ssh_private_key`.
EC-ключ с явными параметрами кривой
иногдаКлючи, созданные некоторыми старыми инструментами или экспортированные из HSM, явно задают простой модуль кривой, её коэффициенты и генератор вместо того, чтобы назвать кривую по OID. Библиотека cryptography намеренно отклоняет такие ключи (RFC 5480 требует для PKIX именованные кривые).
Ключ зашифрован алгоритмом, который cryptography не поддерживает
иногдаТекущие сборки не могут расшифровать файлы PKCS#8, зашифрованные устаревшими схемами PBE (например, PBE-SHA1-RC2 или вариантами DES). Зашифруйте их заново с AES (`openssl pkcs8 -topk8 -v2 aes-256-cbc`).
Как исправить
- 1.
Сначала проверьте ключ с помощью OpenSSL
Если ошибку выдаёт уже `openssl asn1parse`, файл повреждён — получите свежую копию. Если OpenSSL загружает его, а cryptography нет, проверьте кодирование кривой или алгоритм шифрования.
bash openssl asn1parse -in key.pem | head -20 # does the DER parse at all? openssl pkey -in key.pem -noout -text | head # private key: type, curve, size openssl pkey -pubin -in pub.pem -noout -text # public key - 2.
Используйте функцию загрузки, подходящую для ключа
Выбирайте функцию загрузки для PEM, DER или OpenSSH по самим данным, а для открытых ключей используйте функции загрузки открытых ключей.
python from cryptography.hazmat.primitives import serialization def load_any_private_key(data: bytes, password: bytes | None = None): if data.lstrip().startswith(b"-----BEGIN OPENSSH PRIVATE KEY-----"): return serialization.load_ssh_private_key(data, password) if data.lstrip().startswith(b"-----BEGIN"): return serialization.load_pem_private_key(data, password) return serialization.load_der_private_key(data, password) - 3.
Преобразуйте явные параметры в именованную кривую
OpenSSL 3 по умолчанию записывает EC-ключи с именованными кривыми, поэтому одного повторного экспорта ключа достаточно, чтобы ключ с явными параметрами заработал в любой библиотеке.
bash # Re-encode an EC key with a named curve instead of explicit parameters openssl pkey -in explicit.pem -out named.pem openssl ec -in named.pem -param_out -noout -text | grep "ASN1 OID" # e.g. prime256v1
Связанные ошибки
Unable to load PEM file. See https://cryptography.io/en/latest/faq/#why-can-t-i…Python cryptographyValid PEM but no BEGIN PUBLIC KEY/END PUBLIC KEY delimiters. Are you sure this…Python cryptographyPassword was given but private key is not encrypted.Python cryptographyerror:0680009B:asn1 encoding routines:ASN1_get_object:too longOpenSSL 3.x CLI (asn1parse, d2i loaders)