エラーメッセージ
Valid PEM but no BEGIN PUBLIC KEY/END PUBLIC KEY delimiters. Are you sure this is a public key?
Python cryptography — ValueError from load_pem_public_key
このエラーの意味
ファイルは正しい形式の PEM で、フレーミングも解析できますが、ラベルが PUBLIC KEY ではありません。load_pem_public_key に秘密鍵、証明書、CSR のいずれかを渡しています。ライブラリは文字どおり、このオブジェクトに合ったローダーを選んだかどうかを尋ねています。
発生する理由
公開鍵のローダーに秘密鍵を渡している
よくあるBEGIN PRIVATE KEY / BEGIN EC PRIVATE KEY のブロックには load_pem_private_key が必要です。これは、1 つの設定項目(「鍵」)を、実際には鍵ペアの異なる片方を必要とする複数の処理経路で使い回している場合によく起こります。
鍵そのものが想定される場所に証明書を渡している
よくあるBEGIN CERTIFICATE は、X.509 構造の中に公開鍵を含んでいます。まず証明書として読み込み、その後で鍵を取り出す必要があります。どのパーサーがそのオブジェクトを扱うかは、PEM のラベルからわかります。
珍しいが有効なラベル
まれBEGIN CERTIFICATE REQUEST(CSR)のようなオブジェクトや、.pem ファイルに貼り付けた OpenSSH 形式の鍵も、このチェックで失敗します。それぞれに専用のローダーがあるか、変換が必要です。
修正方法
- 1.
手元にあるものから公開鍵を導出する
鍵データを保持するコンテナーであれば、どれでも呼び出しを 1 つ追加するだけで公開鍵を取り出せます。
python from cryptography.hazmat.primitives.serialization import ( load_pem_private_key, load_pem_public_key) from cryptography.x509 import load_pem_x509_certificate first = pem.splitlines()[0] if b"PRIVATE KEY" in first: public_key = load_pem_private_key(pem, password=None).public_key() elif b"CERTIFICATE" in first: public_key = load_pem_x509_certificate(pem).public_key() else: public_key = load_pem_public_key(pem) - 2.
正しい SPKI を一度だけエクスポートする
システムで公開鍵そのものを繰り返し必要とする場合は、正規の BEGIN PUBLIC KEY ファイルを生成して保存しておいてください。
bash openssl pkey -in private.pem -pubout -out public.pem # from a private key openssl x509 -in cert.pem -pubkey -noout > public.pem # from a certificate - 3.
中身がわかるファイル名を付ける
この種の失敗の半分は、コードのエラーではなくファイル管理のミスです。鍵、証明書、チェーンを連結した server.pem や、別のコマンドの出力をコピーして作った public.pem などが該当します。1 つのファイルに 1 つのオブジェクトを保存し、名前にオブジェクトの種類を含めれば(orders-es256-public.pem)、ローダーの取り違えという種類の問題はコードベースから一掃されます。