Lewati ke konten

Keamanan: enkripsi, kebijakan kripto, dan permukaan penandatanganan

Modul keamanan Core menerapkan enkripsi dokumen 256-bit Advanced Encryption Standard (AES-256), mengarahkan setiap pemilihan algoritma melalui kontrak kebijakan kripto, dan mengekspos titik integrasi untuk layanan pengelolaan kunci yang dikelola oleh deployment. Perlindungan dokumen yang efektif bergantung pada penanganan kunci, kekuatan kata sandi, pembaca yang memproses dokumen, dan lingkungan deployment. Halaman ini menyatakan batasan-batasan tersebut secara jelas.

Terminal window
composer require nextpdf/core:^3

Modul keamanan memiliki tiga permukaan. Permukaan enkripsi menggunakan titik masuk dokumen setEncryption() untuk mengonfigurasi penangan keamanan Standard AES-256. Gerbang kebijakan kripto menggunakan CryptoPolicyInterface untuk menentukan hash, tanda tangan, sandi, dan kekuatan kunci mana yang diizinkan oleh suatu deployment. Permukaan penandatanganan dirujuk di sini tetapi didokumentasikan secara terpisah; lihat Penandatanganan.

Enkripsi menggunakan AES-256 sebagaimana didefinisikan dalam ISO 32000-2:2020 §7.6. Jalur baku adalah penangan keamanan Standard V=5 / R=6 dengan filter kripto AESV3. Kunci berkas berukuran 32 byte (256 bit), yang sesuai dengan Federal Information Processing Standards (FIPS) 197. Jalur opsional menambahkan ISO/TS 32003:2023 V=6 / R=7 AES-256 dalam enkripsi terautentikasi Galois/Counter Mode (AES-256-GCM). Halaman mendalam mendokumentasikan kedua jalur: Enkripsi.

Gerbang kebijakan kripto adalah predikat yang menolak atau mengizinkan. Core mengonsultasikan CryptoPolicyInterface sebelum langkah penandatanganan, enkripsi, atau hashing apa pun. Jika tidak ada kebijakan yang ditetapkan, Core mengizinkan setiap algoritma. Default yang terbuka tersebut cocok untuk pengembangan, bukan produksi. Pada deployment yang teregulasi, tetapkan kebijakan eksplisit. Contracts / Security Policy mendokumentasikan permukaan kontraknya.

Flag izin adalah sumber klaim berlebihan yang paling umum, sehingga halaman ini menyatakannya secara eksplisit. Bitmask izin disimpan dalam entri terenkripsi /Perms dan nilai /P. Pembaca yang patuh diharapkan menghormati pembatasan-pembatasan tersebut. Flag tersebut tidak ditegakkan oleh kriptografi. Prosesor yang mengabaikan bit tersebut tetap dapat membaca, menyalin, atau memodifikasi konten setelah memiliki kunci dekripsi. Nyatakan batasan ini kepada pihak mana pun yang mengandalkan flag izin.

Integrasi pengelolaan kunci dan Public-Key Cryptography Standards #11 (PKCS#11) adalah titik-titik kontrak. Core menyertakan jalur kunci lokal. Objek nilai KeyMaterial membungkus kunci 256-bit yang telah diperiksa panjangnya dan menahan pengungkapan dalam keluaran string serta debug. Jalur penjagaan kunci hardware security module (HSM)/PKCS#11 adalah kapabilitas Enterprise yang dibatasi di balik kontrak yang sama; halaman ini menyebut titik integrasinya tetapi tidak mendokumentasikan implementasi Enterprise tersebut.

TipeJenisAnggota utamaStabilitasSejak
Document::setEncryption()metode (concern HasSecurity)userPassword, ownerPassword, permissionsstabil1.0.0
Document::useAesGcm()metode (concern HasSecurity)?bool $enabled — opsional ISO/TS 32003 V=6/R=7stabil2.18.0
Aes256Encryptorclassencrypt(), decrypt(), buildEncryptionDictionary(), verifyUserPassword(), verifyOwnerPassword(), validatePerms()stabil1.0.0
Aes256GcmEncryptorclassencrypt(), decrypt(), encryptStream(), assertWithinSafetyBound(), invocationCount()stabil2.18.0
KeyMaterialfinal readonly classgenerate(), exposeKey(), fingerprint()stabil2.18.0
CryptoPolicyInterfaceinterfaceisHashAlgorithmAllowed(), isSignatureAlgorithmAllowed(), isEncryptionAlgorithmAllowed(), isKeyStrengthAllowed(), getPreferredHashAlgorithm(), getName()stabil1.9.0
Config::withCryptoPolicy()metodeCryptoPolicyInterface $policystabil1.9.0
CryptoCapabilitiesfinal classhasAesGcm(), detectFipsMode(), assertFipsAvailableForProfile()stabil2.0.0
examples/22-protection.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->setTitle('Encrypted Document — Restricted Permissions');
// Call setEncryption() BEFORE addPage().
// Permission bit 3 (value 4) = printing allowed; all other operations denied.
$doc->setEncryption(
userPassword: 'demo',
ownerPassword: 'admin',
permissions: 4,
);
$doc->addPage();
$doc->setFont('helvetica', 'B', 20);
$doc->cell(0, 14, 'Encrypted PDF Document', newLine: true);
$doc->save(__DIR__ . '/output/22-protection.pdf');

Kata sandi pengguna membuka dokumen. Kata sandi pemilik memberikan akses penuh. Flag izin hanya membatasi pembaca yang patuh.

examples/security/policy-gated-encryption.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\CryptoPolicyInterface;
use NextPDF\Core\Document;
use Psr\Log\LoggerInterface;
final readonly class PolicyGatedEncryption
{
public function __construct(
private CryptoPolicyInterface $cryptoPolicy,
private LoggerInterface $logger,
) {}
/**
* Encrypt only when the active policy permits AES-256-CBC.
*
* @param non-empty-string $userPassword Opens the document.
* @param non-empty-string $ownerPassword Grants full access.
*/
public function protect(
Document $doc,
string $userPassword,
string $ownerPassword,
int $permissions,
): void {
if (!$this->cryptoPolicy->isEncryptionAlgorithmAllowed('aes-256-cbc')) {
$this->logger->error('Encryption refused by crypto policy', [
'policy' => $this->cryptoPolicy->getName(),
]);
throw new \RuntimeException('AES-256-CBC denied by the active crypto policy.');
}
$doc->setEncryption($userPassword, $ownerPassword, $permissions);
$this->logger->info('Document encrypted', [
'policy' => $this->cryptoPolicy->getName(),
'algorithm' => 'aes-256-cbc',
]);
}
}

Gerbang ini mengonsultasikan kebijakan sebelum enkripsi, mencatat nama kebijakan untuk jejak audit, dan melempar pengecualian spesifik ketika kebijakan menolak algoritma enkripsi tersebut.

  • Panggil setEncryption() sebelum addPage(). Panggilan setelah itu tidak mengenkripsi secara retroaktif konten yang sudah dikeluarkan oleh penulis.
  • Mode PDF/A dan enkripsi bersifat saling eksklusif. ISO 19005 melarang kunci trailer Encrypt dalam setiap varian PDF/A, sehingga setEncryption() dan useAesGcm() melempar pengecualian ketika manajer PDF/A aktif.
  • Di dalam setEncryption(), kata sandi pemilik yang kosong akan menggunakan kata sandi pengguna sebagai fallback. Dokumen dengan satu kata sandi bersama memberikan akses tingkat pemilik kepada pemegang kata sandi pengguna.
  • Ketika tidak ada kebijakan yang diinjeksikan, CryptoPolicyInterface mengizinkan setiap algoritma. Perlakukan default terbuka sebagai kemudahan pengembangan, dan tetapkan kebijakan eksplisit pada deployment teregulasi mana pun.
  • Flag izin bersifat anjuran bagi pembaca. Jangan menggambarkannya sebagai kontrol akses yang tidak dapat dilewati oleh prosesor yang berniat jahat.

setEncryption() menjalankan rutin penurunan kunci berulang (Algorithm 2.B, revisi 6) selama pembangunan dokumen. Biayanya terbatas dan konstan per dokumen; tidak meningkat seiring jumlah halaman. Enkripsi per objek melakukan satu operasi AES per aliran atau string. Jalur opsional AES-256-GCM menambahkan overhead 28 byte per objek (vektor inisialisasi (IV) 12 byte ditambah tag 16 byte) dan melakukan streaming konten besar dalam potongan 16 MiB. Ini menjaga jalur streaming tetap di bawah puncak 64 MB yang terdokumentasi. performance_budget sebesar 1500 ms wall dan puncak 64 MB didominasi oleh rendering dokumen, bukan enkripsi.

Model ancaman dinyatakan secara eksplisit. Gerbang kebijakan kripto memitigasi penurunan tingkat algoritma dengan menolak sandi lemah, hash lemah, dan kunci pendek sebelum operasi apa pun. Mesin tidak diam-diam mengganti ke primitif yang lebih lemah ketika yang diminta tidak tersedia; ia melempar pengecualian sehingga operator dapat bertindak. KeyMaterial memitigasi pengungkapan kunci melalui pencatatan: bentuk string dan debug-nya menyamarkan byte tersebut dan hanya mengekspos sidik jari yang tidak dapat dibalik. Perusakan ciphertext hanya terdeteksi pada jalur opsional AES-256-GCM, tempat tag autentikasi diverifikasi dan ketidakcocokan melempar pengecualian alih-alih mengembalikan plaintext. Jalur baku AES-256 Cipher Block Chaining (AES-256-CBC) hanya untuk kerahasiaan dan tidak mendeteksi modifikasi dengan sendirinya. Pada jalur GCM, penggunaan ulang IV dimitigasi oleh penghitung monotonik ditambah set kolisi pertahanan-berlapis, konsisten dengan persyaratan IV unik dalam NIST SP 800-38D §8.

Batasannya juga dinyatakan secara eksplisit. Enkripsi AES-256 diterapkan sebagaimana didefinisikan dalam ISO 32000-2:2020 §7.6. Perlindungan yang efektif bergantung pada kekuatan kata sandi, pengelolaan kunci, lingkungan deployment, dan pembaca yang memproses dokumen. Pembaca yang patuh menghormati flag izin, tetapi kriptografi tidak menegakkannya. Probe mode FIPS melaporkan apakah build OpenSSL host telah memuat penyedia FIPS. Pustaka beroperasi dalam mode yang kompatibel dengan FIPS ketika host menyediakan modul yang tervalidasi; ia tidak menyertifikasi modul apa pun. NIST SP 800-57 Part 1 §4 menetapkan masa pakai kunci dan cryptoperiod sebagai tanggung jawab deployment. Core mengekspos kontrol tersebut, dan deployment menetapkan kebijakan rotasinya.

Permukaan enkripsi tidak mengirimkan byte dokumen, termasuk informasi pengenal pribadi (PII) apa pun yang dikandungnya, ke luar host. Penurunan kunci, enkripsi, dan dekripsi berjalan dalam proses. Jalur opsional GCM mengindeks set kolisi IV dalam memori berdasarkan sidik jari kunci yang tidak dapat dibalik, bukan berdasarkan byte kunci. Modul keamanan tidak menulis nilai kata sandi atau kunci apa pun ke disk. Deployment yang mengarahkan kunci melalui layanan pengelolaan kunci eksternal bertanggung jawab atas residensi layanan tersebut.

KeyMaterial::__toString() dan __debugInfo() mengembalikan placeholder yang disamarkan, sehingga pencatatan objek kunci yang tidak disengaja menghasilkan sidik jari, bukan byte kunci. Kata sandi yang diteruskan ke setEncryption() membawa atribut #[\SensitiveParameter], yang menyamarkannya dari stack trace. Untuk audit, gunakan nama kebijakan dari CryptoPolicyInterface::getName() dan sidik jari kunci 8 karakter sebagai pengenal operasi kripto. Catat nilai-nilai tersebut, jangan pernah kunci atau kata sandinya.

AncamanMitigasi di CoreBatasan residual
Penurunan tingkat algoritma / penggantian sandi lemahGerbang kebijakan kripto; tanpa degradasi diam-diam (melempar UnsupportedAlgorithmException)Efektif hanya ketika sebuah kebijakan diinjeksikan
Pengungkapan kunci melalui logPenyuntingan KeyMaterial; #[\SensitiveParameter] pada kata sandiPemanggil yang meneruskan exposeKey() ke logger membatalkan mitigasi ini
Perusakan ciphertextVerifikasi tag GCM pada jalur opsionalJalur baku CBC hanya untuk kerahasiaan
Penggunaan ulang IV (GCM)Penghitung monotonik ditambah set kolisi; rollover ditolak
Pelewatan flag izinTidak ada; flag bersifat anjuranPembaca yang tidak patuh mengabaikan flag tersebut
Brute-force pada kata sandi lemahSASLprep ditambah penurunan kunci berulang meningkatkan biaya seranganKata sandi lemah tetap menjadi risiko yang dominan

Core bukan modul kriptografi yang tervalidasi FIPS dan tidak tersertifikasi FIPS. CryptoCapabilities::detectFipsMode() adalah probe runtime best-effort: ia membaca override operator, lalu daftar penyedia OpenSSL, lalu panggilan mode FIPS lawas, dan melaporkan aktif, absen, atau tak tentu. assertFipsAvailableForProfile() gagal-tertutup ketika profil FIPS dipilih pada host yang tidak dapat membuktikan adanya penyedia FIPS. Pustaka beroperasi dalam mode yang kompatibel dengan FIPS ketika dikonfigurasi untuk menggunakan build OpenSSL host yang telah memuat penyedia tervalidasi FIPS. Postur FIPS yang tervalidasi dan tersertifikasi adalah ranah Enterprise; lihat dokumentasi Enterprise.

KlaimStandarKlausaBukti
Jalur GCM menjaga setiap IV tetap unik untuk satu invokasi, konsisten dengan persyaratan keunikan standar.NIST SP 800-38D§8.2.1
Core mengekspos kontrol untuk masa pakai kunci dan cryptoperiod; deployment bertanggung jawab atas kebijakannya.NIST SP 800-57 Part 1 Rev. 5§4
Kunci berkas AES berukuran 256 bit, yang sesuai dengan panjang kunci standar.FIPS 197§4.2.1
Pembangkitan kunci yang berada di token adalah titik integrasi untuk penyimpanan kunci eksternal.OASIS PKCS#11 v3.1C_GenerateKey

ISO 32000-2:2020 §7.6 adalah dasar normatif untuk penangan keamanan Standard. Teksnya dibatasi oleh lisensi dan diparafrasekan di sini, tidak pernah dikutip; halaman ini menyebut klausanya berdasarkan nomor. Setiap poin di atas diparafrasekan dari standar yang dikutip.

Core mendefinisikan dan membekukan kontrak kebijakan kripto, menyertakan jalur enkripsi AES-256, dan menyediakan permukaan kunci lokal. Edisi Enterprise menyediakan jalur penjagaan kunci HSM/PKCS#11 dan profil kebijakan kripto mode FIPS di balik CryptoPolicyInterface yang sama. Permukaan kontraknya identik di seluruh edisi; deployment menginjeksikan implementasi kebijakan dan backend penjagaan kunci yang berbeda.