Сообщение об ошибке
Unable to load PEM file. See https://cryptography.io/en/latest/faq/#why-can-t-i-import-my-pem-file for more details. MalformedFraming
Предложение перед токеном не меняется; токен называет, что пошло не так. MalformedFraming означает, что строки BEGIN/END не найдены; MismatchedTags("PRIVATE KEY", "PUBLIC KEY") — что они не совпадают; InvalidData(Invalid symbol 92, offset 0.) — что тело не в base64: 92 — это обратная косая черта, признак буквальных последовательностей \n.
Python cryptography — ValueError from load_pem_* functions
Что это означает
load_pem_private_key / load_pem_public_key / load_pem_x509_certificate не нашли целого PEM-обрамления — парных строк BEGIN и END с телом в base64 между ними. Токен в конце (здесь MalformedFraming) — диагноз парсера; ссылка на FAQ входит в сам текст ошибки.
Почему это происходит
PEM обрезан или скопирован не полностью
частоОтсутствующая строка END (буфер обмена обрезал текст, блочный скаляр YAML «съел» последнюю строку) ломает обрамление. Каждый PEM должен заканчиваться парной строкой -----END ...-----. Пустое значение (незаданный секрет) даёт тот же MalformedFraming.
Экранированные переводы строк из окружения или конфигурации
частоPEM, переданные через файлы .env, docker-compose, манифесты Kubernetes или JSON, часто приходят одной строкой с буквальными последовательностями \n. Функция загрузки выдаёт то же предложение с InvalidData(Invalid symbol 92, offset 0.) в конце.
Повреждённые маркеры BEGIN или END
иногдаМаркер, потерявший дефис, или похожие на дефисы тире, вставленные из редактора документов, больше не обрамляют блок; метка END, отличающаяся от метки BEGIN, приводит к MismatchedTags. При этом cryptography 50 допускает кавычки вокруг блока, отступы YAML, BOM UTF-8 и окончания строк CRLF.
Склеенный пакет с повреждённым разделителем
редкоФайлы цепочек с несколькими блоками PEM не загружаются целиком, если один блок потерял строку END: тогда функция загрузки выдаёт InvalidData(Invalid symbol 45, …), где 45 — первый дефис следующей строки BEGIN. Функция загрузки сообщает об ошибке в файле, а не в блоке, поэтому ищите делением пополам: разбейте пакет и загрузите каждый объект по отдельности, чтобы найти повреждённый.
Как исправить
- 1.
Нормализуйте перед загрузкой
Восстановите переводы строк, уберите пробельные символы и кавычки по краям и проверьте первую строку, прежде чем передавать байты функции загрузки.
python import os pem = os.environ["PRIVATE_KEY"].replace("\\n", "\n").strip().strip('"').encode() assert pem.startswith(b"-----BEGIN"), pem[:30] from cryptography.hazmat.primitives.serialization import load_pem_private_key key = load_pem_private_key(pem, password=None) - 2.
Используйте файлы или встроенные многострочные секреты
Смонтированные файлы секретов полностью снимают проблему экранирования; Kubernetes Secrets и большинство хранилищ секретов могут передать PEM байт в байт.
python with open("/run/secrets/signing_key.pem", "rb") as f: key = load_pem_private_key(f.read(), password=None) - 3.
Проверьте обрамление программно
Быстрая проверка того, что строки BEGIN/END есть и совпадают, сразу показывает, где искать проблему: в содержимом или в способе передачи.
python lines = pem.decode().splitlines() print(lines[0]) # -----BEGIN PRIVATE KEY----- print(lines[-1]) # -----END PRIVATE KEY-----