コンテンツにスキップ

AES-256 で PDF を暗号化し、権限を設定する

このレシピでは、AES-256 でドキュメントを暗号化します。ユーザーパスワードとオーナーパスワードを設定し、権限ビットマスクで操作を制限します。このレシピはexamples/22-protection.phpに沿っています。

再現性 — このレシピがbitwiseではなくstructuralである理由。 AES-256 の PDF は、同一の入力とパスワードを使用しても、2 回の実行でバイト単位まで同一になることはありません。リビジョン 6 の標準セキュリティハンドラーは、暗号化のたびに強力な乱数生成器を使用して、16 バイトの新しいランダムバイト(user/owner の検証ソルトとキーソルト)を生成し、 その後にファイル暗号化鍵を導出します (ISO 32000-2 §7.6.4、Algorithm 2.B)。 AES-256-CBC は、オブジェクトごとにランダムな初期化ベクトルを使用します。トレーラーの /IDも同様に、2 つのバイト文字列からなる配列であり、その最初の要素は作成時にファイルから導出された永続的な識別子です(ISO 32000-2 §14.4)。 したがって再現性プロファイルはstructuralです。ハーネスは暗号化ソルト/IV、オブジェクトの順序、トレーラーの/IDを正規化したうえで 2 回の実行を比較します。実現不可能なバイト一致を表明することはありません。

  • Core がインストールされていること: composer require nextpdf/core:^3
  • AES-256 エンクリプターが使用するopenssl PHP 拡張機能が有効であること。
  1. ドキュメントを作成します。
  2. 先に setEncryption() を、続いて addPage() を呼び出します。エンクリプターは、いずれかのコンテンツオブジェクトが書き込まれる前に存在している必要があります。
  3. ユーザーパスワード(ドキュメントを開くために必要)、オーナーパスワード(フルアクセス)、権限ビットマスクを渡します。
  4. コンテンツを追加して保存します。ライターは各オブジェクトのボディを暗号化します。
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
// Permission bits (ISO 32000-2, encryption dictionary P entry):
// bit 3 (4) allow printing
// bit 4 (8) allow content modification
// bit 5 (16) allow text extraction / copying
// bit 6 (32) allow annotation and form editing
// Grant printing only:
$permissions = 4;
$doc = Document::createStandalone();
$doc->setTitle('Encrypted Document');
// setEncryption() MUST run before addPage(). Order matters.
$doc->setEncryption(
userPassword: 'open-me',
ownerPassword: 'owner-secret',
permissions: $permissions,
);
$doc->addPage();
$doc->setFont('helvetica', '', 12);
$doc->cell(0, 10, 'This document is encrypted with AES-256.', newLine: true);
$doc->save(__DIR__ . '/encrypted.pdf');
echo "Wrote encrypted.pdf (AES-256, printing only)\n";
Wrote encrypted.pdf (AES-256, printing only)

ファイル encrypted.pdf を開くと、パスワードの入力を求められます。ユーザーパスワードを使用すると、制限された権限セットのもとでドキュメントが開きます。オーナーパスワードを使用すると、フルアクセスでドキュメントが開きます。

  • 呼び出し順序。 setEncryption()addPage() の後に呼び出しても、それ以前のコンテンツがさかのぼって暗号化されることはありません。必ず最初に暗号化を構成してください。
  • オーナーパスワードのデフォルト。 オーナーパスワードが空の場合、エンジンはユーザーパスワードをオーナーパスワードとして再利用します。2 つのロールを区別する必要がある場合は、それぞれ異なるパスワードを設定してください。
  • 権限のセマンティクス — 境界。 権限ビットは、準拠するリーダーによって尊重されます。これらは暗号的に強制されるものではありません。ビットを無視するリーダーや、オーナーパスワードを使用するツールは、制限された操作を実行できます。権限は、意図的な攻撃者に対抗するアクセス制御としてではなく、協調するソフトウェアへのポリシーシグナルとして扱ってください。
  • PDF/A との競合。 PDF/A は、Encryptトレーラーキーを禁止しています。PDF/A ドキュメントに対してsetEncryption()を呼び出すと、順序にかかわらず、非互換例外がスローされます。PDF/A-4適合ゲートを参照してください。
  • AES-256-GCM。 useAesGcm()は、ホストの OpenSSL または libsodium がこの暗号を提供している場合に、ISO/TS 32003 の GCM バルク暗号化を選択します。それ以外の場合は、InvalidConfigExceptionをスローします。
記述仕様箇条リファレンス ID
標準セキュリティハンドラーは、暗号化アルゴリズムと鍵長を定義します。ISO 32000-2§7.6
暗号化ディクショナリのPエントリーは、権限ビットを保持します。ISO 32000-2§7.6

暗号化は、パスワードを持たない者に対してコンテンツの機密性を保護します。権限ビットはリーダーに対する助言であり、それ自体では、非準拠のツールの動作を防ぐことはできません。