Перейти к содержимому
ecdsa.com
Python cryptographyPython: пакет cryptography

Сообщение об ошибке

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 входит в сам текст ошибки.

Почему это происходит

Как исправить

  1. 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. 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. 3.

    Проверьте обрамление программно

    Быстрая проверка того, что строки BEGIN/END есть и совпадают, сразу показывает, где искать проблему: в содержимом или в способе передачи.

    python
    lines = pem.decode().splitlines()
    print(lines[0])   # -----BEGIN PRIVATE KEY-----
    print(lines[-1])  # -----END PRIVATE KEY-----

Связанные ошибки

Открыть всю базу ошибок подписей