コンテンツにスキップ
getnextpdf.com

PDF 暗号化の本当の仕組み — そしてその限界

Spec: ISO 32000-2, §7.6

PDF 暗号化は、文書の内側にある語と画像を撹拌し、正しいパスワードを持つ者だけが読めるようにします。それは本物の暗号であり、自身が担う唯一の仕事をうまくこなします。それはまた、広く誤解されてもいます。同じ機能が、ロックに見えてそうではない第 2 のメカニズム — パーミッションフラグ — を携えているからです。

このページはその 2 つを切り分けます。AES-256 が実際に保護するもの、2 つのパスワードが本当は何のためにあるのか、そして率直な境界がどこに位置するかを説明します。

人が暗号化に手を伸ばすのは、文書が機微なものであるとき — 契約書、給与明細、診断書 — です。その期待は妥当です。これを非公開に保ち、人々が印刷したりコピーしたりするのを止めてほしい、というものです。PDF はその願いの前半を説得力をもって叶え、後半は名誉に基づく約束としてのみ叶えます。

その 2 つを取り違えるところに、コストが落ちます。チームがファイルを「コピー不可」とマークし、プラットフォームがそれを強制すると信じて、出荷します。数か月後、誰かが別のリーダーで 30 秒のうちにテキストをコピーし、そもそも成り立っていなかった前提が、静かに漏えいへと変わります。暗号化が破られたわけではありません。それは単に、自身が行わないことを求められただけです。

  • 暗号化は機密性を保護します。 AES-256 を使えば、PDF の文字列とストリームのコンテンツは本物の暗号文です。鍵がなければ、それは読めません。
  • ユーザーパスワードは文書を開きます。 それを与えればコンテンツを見られます。それがなければ、読むものは何もありません。
  • オーナーパスワードはパーミッションを統べます。 それは「全権限」の鍵です。それが守るパーミッションフラグ — 印刷、コピー、変更 — は、暗号化された文書の内側に記録されています。
  • パーミッションフラグはリーダー協調的です。 それは行儀のよいリーダーへのお願いであって、強制ではありません。それを無視するリーダーは、いずれにせよ印刷、コピー、編集できます。
  • 構造は見えたままです。 暗号化はコンテンツを隠すのであって、文書の骨格を隠すのではありません — ページ数やオブジェクトのレイアウトは秘密ではありません。

PDF 暗号化は Spec: ISO 32000-2, §7.6 によって定義されます。モデルは精密です。セキュリティハンドラー がパスワードからファイル暗号化鍵を導出し、文書の文字列とストリームがその鍵で暗号化され、暗号化ディクショナリ — ファイルトレーラーから参照される — が、どの暗号が使われたか、鍵がどれだけ長いか、そして作者がどのパーミッションを宣言したかを記録します。

現代の推奨される暗号は、256 ビット鍵の AES です。この方法で PDF を暗号化すると、読み取り可能なペイロード — あなたが抽出するであろうテキスト、画像のバイト、フォントデータ — は暗号文へと変換されます。文書の外側の形は、設計上、読み取り可能なまま残ります。リーダーは、あなたにパスワードを尋ねる前に、暗号化ディクショナリを見つけて鍵長を知らなければなりません。だからこそ暗号化は、ファイル全体 の不透明化ではなく、コンテンツ の機密性として理解するのが最善なのです。

2 つのパスワードは異なるレイヤーに位置しており、その区別こそが、最も正しく押さえる価値のある部分です。

  1. A password is suppliedEither the user password (open) or the owner password (full rights).
  2. The security handler derives the keyISO 32000-2 §7.6.4 turns the password into the file encryption key.
  3. Content is decryptedAES-256 turns the encrypted strings and streams back into readable bytes.
  4. Permissions are consultedThe owner key grants all rights; the user key is bound by the declared permission flags — if the reader chooses to honour them.
How a password becomes readable content: the user password (or the owner password) is run through the standard security handler's key-derivation routine to recover the file encryption key, which then decrypts the document's strings and streams. The owner password additionally unlocks the full set of permissions; the user password is bound by whatever permission flags the author declared.

ユーザーパスワード は、開くためのパスワードです。それは一つの問いに答えます。そもそもあなたはコンテンツを見てよいのか、というものです。ユーザーパスワードがなければ、読み取り可能な文書はありません — その部分は暗号的に強制されます。導出された鍵がなければ、復号するものが何もないからです。

オーナーパスワード は、パーミッションのためのパスワードです。ファイルは誰でも開ける(ユーザーパスワードなし)にもかかわらず、「全権限」のアクション — 高解像度での印刷、テキストのコピー、ファイルの変更 — をゲートするオーナーパスワードを宣言できます。重要なのは、オーナーパスワードが守るパーミッションビットが、標準セキュリティハンドラーによって完全性保護されていることです。それらの改ざんは、準拠リーダーによって検出され、拒否されます。ハンドラーが、宣言されたパーミッションを暗号化鍵に結び付けるからです。これらのビットは、文字どおり読めない・編集できないバイトではありません — 攻撃者はそれらを変更できます — が、変更されたコピーは検証を通らないため、準拠リーダーはそれを破損として扱います。それらは改ざん検知可能です。ただ単に、自己強制的 ではないのです。

暗号化の設定は表現が簡単です。重要なのは、その結果を率直に読むことです。これは意図を設定するものであり、その意図のうちパーミッションの部分は助言的です。

<?php
declare(strict_types=1);
use NextPDF\Core\Document;
use NextPDF\Security\Encryption\EncryptionMode;
use NextPDF\Security\Encryption\Permission;
$document = Document::createStandalone();
$document->setTitle('Confidential Offer');
$document->addPage();
// Confidentiality is real: AES-256 means the content is unreadable
// without the user password. This half is cryptographically enforced.
$document->encrypt(
userPassword: 'open-sesame',
ownerPassword: 'full-rights-key',
mode: EncryptionMode::Aes256,
// Permissions are a declared request to a cooperating reader,
// recorded inside the encrypted document — not a hard lock.
permissions: Permission::Print->value | Permission::CopyContent->value,
);
$document->save('offer.pdf');

ユーザーパスワードとオーナーパスワードは、異なる仕事を持つ異なる鍵です。permissions 引数は、行儀のよいリーダーが何を許す べき かを述べます。それは誠実なメタデータであり、改ざんが検出可能になるようセキュリティハンドラーによって完全性保護されています — そしてそれが、生成側のライブラリが約束できることの上限です。

落とし穴は、「パーミッション」を「強制」と読むことです。それは直観的です。フラグが 印刷不可 と言うのだから、当然印刷はブロックされるはずだ、と。しかし PDF の中の何かが手を伸ばして、リーダーの印刷ボタンを無効化することはできません。パーミッション整数は、協調する リーダーが守るために記録されています。協調しないことを選ぶリーダーは — そして、そうするものはいくつもあります — 自由に印刷、コピー、編集できます。

NextPDF はこれについて意図的です。コア暗号化パスは、パーミッションフラグを宣言された意図として扱い、それを強制するふりは決してしません。アクションを本当に防ぎたいのなら、その制御はファイルの外側に存在しなければなりません — 誰に文書を渡すか、あるいはその周りのアクセス制御システムの中に。

それぞれの半分が何を保証するかについて、精密でいてください。暗号化(ユーザーパスワードのレイヤー)は本物の機密性制御です。パスワードが強ければ強く、あなたが選ぶ秘密の良し悪しがそのまま強さになります。パーミッション(オーナーパスワードのレイヤー)は改ざん検知可能なメタデータであって、アクセス制御ではありません。

What you might expectWhat encryption actually delivers
パスワードなしには誰もコンテンツを読めない真。AES-256 と強力なユーザーパスワードがあれば、文字列とストリームは鍵なしには読めません。本当に強制されます。
誰も「コピー不可」を「コピー許可」に書き換えられない改ざん検知可能であって、不可能ではありません。パーミッションフラグは標準セキュリティハンドラーによって完全性保護されています。部外者はバイトを編集できますが、変更されたコピーは検証を通らないため、準拠リーダーは変更を検出して拒否します。
リーダーがコピーや印刷を妨げられるいかなる PDF 生成側によっても保証されません。非協調的なリーダーはフラグを無視できます。これはフォーマットの性質であって、NextPDF の限界ではありません。

さらに 2 つの境界を、はっきり述べる価値があります。第一に、暗号化は コンテンツ を保護するのであって、文書の構造を保護するのではありません。オブジェクトのレイアウトとページ数は見えたままであり、それはリーダーが暗号化ディクショナリを見つけるために通常かつ必要なことです。第二に、暗号化された PDF は、アーカイブ用の PDF/A 準拠を同時に主張することはできません — そのプロファイルは Encrypt エントリを禁じているため、あなたはどちらか一方を選ぶことになります。暗号化とパーミッションのトラブルシューティングページが、その具体的な例外と PDF/A の拒否を詳しく扱います。

  • The standards landscape — ISO 32000-2 とその暗号化に関する条項が、PDF 標準の中でどこに位置するか。
  • Encryption and permission flags — 実務的なエントリ。復号の失敗、そしてコード上のパーミッションの境界。
  • What a PDF actually is — 暗号化が保護するオブジェクトモデルと、それが見えたまま残す構造。
  • How signatures sit in a PDF — 文書の信頼のもう一方の半分。暗号化は隠し、署名は証明します。
  • AES-256 — 256 ビット鍵を持つ Advanced Encryption Standard。PDF コンテンツの暗号化に推奨される現代の暗号。
  • ユーザーパスワード(開くパスワード) — 暗号化された文書を開いて読むために必要な秘密。それがなければ、コンテンツは復号できません。
  • オーナーパスワード(パーミッションパスワード) — パーミッションフラグを統べる「全権限」の秘密。文書は、開くのにユーザーパスワードを必要とせずに、これを持つことができます。
  • パーミッションフラグ — 暗号化ディクショナリに格納された、宣言された印刷・コピー・変更の意図。改ざんが検出可能なよう完全性保護されていますが、協調するリーダーによってのみ守られます。
  • セキュリティハンドラー — パスワードからファイル暗号化鍵を導出するコンポーネント。ISO 32000-2 の標準セキュリティハンドラーによって定義されます。
  • リーダー協調的(Reader-cooperative) — ファイル自体によって強制されるのではなく、消費する側のソフトウェアがそれに従うことを選ぶかどうかに依存する制御。