ข้ามไปยังเนื้อหา

เข้ารหัสลับ PDF ด้วย AES-256 และกำหนดสิทธิ์

ใช้สูตรนี้เพื่อเข้ารหัสลับเอกสารด้วย AES-256 โดยกำหนดรหัสผ่านผู้ใช้ รหัสผ่านเจ้าของ และบิตมาสก์สิทธิ์ที่จำกัดการดำเนินการที่อนุญาต สูตรนี้ใช้ examples/22-protection.php เป็นแม่แบบ

ความสามารถในการทำซ้ำ — เหตุใดสูตรนี้จึงเป็นแบบ structural ไม่ใช่ bitwise ไฟล์ PDF แบบ AES-256 จะไม่เหมือนกันในระดับไบต์ในการรันแต่ละครั้ง แม้จะใช้อินพุต และรหัสผ่านเดียวกัน ก่อนที่จะได้คีย์การเข้ารหัสลับไฟล์ standard security handler revision-6 จะสร้างไบต์สุ่มใหม่ 16 ไบต์ (สำหรับ user/owner salt ในการตรวจสอบและคีย์) ทุกครั้งที่เข้ารหัสลับด้วยตัวสร้างเลขสุ่ม ที่มีความแข็งแกร่ง (ISO 32000-2 §7.6.4, Algorithm 2.B) AES-256-CBC ใช้ initialization vector แบบสุ่มสำหรับแต่ละออบเจกต์ ส่วน trailer /ID ก็เป็นอาร์เรย์ของ byte string สองตัวเช่นกัน องค์ประกอบแรกเป็นตัวระบุถาวร ที่ได้มาจากไฟล์ ณ เวลาที่สร้าง (ISO 32000-2 §14.4) ดังนั้นโปรไฟล์ความสามารถในการทำซ้ำจึงเป็นแบบ structural ก่อนเปรียบเทียบการรันสอง ครั้ง harness จะปรับ salt/IV ของการเข้ารหัสลับ ลำดับออบเจกต์ และ /ID ของ trailer ให้อยู่ในรูปแบบบัญญัติ แทนที่จะยืนยันการตรงกันระดับไบต์ซึ่งเป็นไปไม่ได้

  • ติดตั้ง Core ด้วยคำสั่ง composer require nextpdf/core:^3 ให้เรียบร้อย
  • เปิดใช้ส่วนขยาย PHP openssl ซึ่งตัวเข้ารหัสลับ AES-256 ต้องใช้
  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() จะไม่ย้อนกลับไปเข้ารหัสลับเนื้อหาที่เพิ่มไว้ก่อนหน้านั้น ควรกำหนดค่าการเข้ารหัสลับไว้ก่อนเสมอ
  • ค่าเริ่มต้นของรหัสผ่านเจ้าของ หากรหัสผ่านเจ้าของว่างเปล่า เอนจินจะใช้รหัสผ่านผู้ใช้เป็นรหัสผ่านเจ้าของ กำหนดรหัสผ่านคนละค่าเมื่อบทบาทเหล่านี้ต้องแยกจากกัน
  • ความหมายของสิทธิ์ — ขอบเขต โปรแกรมอ่านที่สอดคล้องตามมาตรฐานจะเคารพบิตสิทธิ์ แต่บิตเหล่านี้ไม่ได้ถูกบังคับใช้ด้วยการเข้ารหัสลับ โปรแกรมอ่านที่ละเลยบิตดังกล่าว หรือเครื่องมือที่ใช้ร่วมกับรหัสผ่านเจ้าของ ยังสามารถดำเนินการที่ถูกจำกัดได้ ให้ถือว่าสิทธิ์เป็นสัญญาณเชิงนโยบายสำหรับซอฟต์แวร์ที่ให้ความร่วมมือ ไม่ใช่การควบคุมการเข้าถึงที่ต้านทานผู้ที่ตั้งใจหลีกเลี่ยงข้อจำกัดได้
  • ความขัดแย้งกับ PDF/A PDF/A ห้ามใช้คีย์ trailer Encrypt การเรียก setEncryption() บนเอกสาร PDF/A ไม่ว่าจะเรียกในลำดับใด จะส่ง exception เรื่องความไม่เข้ากัน ดู เกตการสอดคล้องตามมาตรฐาน PDF/A-4 เพิ่มเติม
  • AES-256-GCM useAesGcm() เลือกใช้การเข้ารหัสลับข้อมูลจำนวนมากแบบ GCM ตาม ISO/TS 32003 เมื่อ OpenSSL หรือ libsodium ของโฮสต์มีไซเฟอร์ดังกล่าว มิฉะนั้นจะส่ง InvalidConfigException ออกมา
ข้อความข้อกำหนดข้อรหัสอ้างอิง (reference_id)
standard security handler กำหนดอัลกอริทึมการเข้ารหัสลับและความยาวของคีย์ISO 32000-2§7.6
รายการ P ใน encryption dictionary เก็บบิตสิทธิ์ISO 32000-2§7.6

การเข้ารหัสลับปกป้องความลับของเนื้อหาจากผู้ที่ไม่มีรหัสผ่าน บิตสิทธิ์เป็นเพียงคำแนะนำสำหรับโปรแกรมอ่าน และโดยลำพังแล้วไม่ได้ป้องกันเครื่องมือที่ไม่สอดคล้องตามมาตรฐานจากการดำเนินการใดๆ