Szyfrowanie: AES-256 (CBC) i AES-256-GCM
W skrócie
Dział zatytułowany „W skrócie”Core szyfruje pliki w formacie Portable Document Format (PDF) algorytmem AES-256 (Advanced Encryption Standard z kluczami 256-bitowymi) zgodnie ze standardowym programem obsługi zabezpieczeń z normy ISO 32000-2:2020 §7.6. Tryb domyślny to V=5 / R=6 / AESV3 (AES-256-CBC, Cipher Block Chaining). Opcjonalna uwierzytelniona ścieżka to AES-256-GCM (Galois/Counter Mode) V=6 / R=7 z normy ISO/TS 32003:2023. Ta strona definiuje wyprowadzanie klucza, format transmisji, granicę uprawnień oraz ograniczenia wdrożeniowe.
Instalacja
Dział zatytułowany „Instalacja”composer require nextpdf/core:^3Ścieżka domyślna wymaga rozszerzenia openssl. Ścieżka AES-256-GCM korzysta z openssl lub ext-sodium. Na hostach bez sprzętowej obsługi AES-NI libsodium odmawia wykonywania GCM; Core przełącza się wtedy na wolniejszą implementację OpenSSL, nie zmieniając algorytmu.
Przegląd koncepcyjny
Dział zatytułowany „Przegląd koncepcyjny”Domyślny mechanizm korzysta ze standardowego programu obsługi zabezpieczeń V=5 / R=6 z filtrem szyfrującym AESV3. Po wywołaniu setEncryption() Core generuje losowy 256-bitowy klucz pliku z kryptograficznego źródła losowości platformy (random_bytes()). Klucz ma 32 bajty, co odpowiada długości klucza według FIPS 197. Core szyfruje zawartość poszczególnych obiektów algorytmem AES-256-CBC. Na początku każdego szyfrogramu dołącza 16-bajtowy wektor inicjujący, zgodnie z wytycznymi normy ISO 32000-2:2020 §7.6.4.
Wyprowadzanie klucza przebiega zgodnie z Algorytmem 2.B w wersji 6. Core najpierw normalizuje hasło za pomocą SASLprep (RFC 4013), a następnie skraca je do 127 bajtów UTF-8 na granicy znaku, zgodnie z wytycznymi normy ISO 32000-2:2020 §7.6.4.3.3. Wyprowadzony skrót oblicza iterowaną procedurą SHA-256 / SHA-384 / SHA-512 sterowaną krokiem AES-128-CBC, co zwiększa koszt zgadywania hasła w trybie offline. Core generuje sole użytkownika, właściciela oraz sole poszczególnych kluczy raz dla danego egzemplarza szyfratora, dzięki czemu jeden egzemplarz emituje deterministyczne bajty słownika. Jest to warunek wstępny dla wieloprzebiegowego mechanizmu zapisu.
useAesGcm() włącza opcjonalną ścieżkę AES-256-GCM. Implementuje ona filtr szyfrujący AESV4 V=6 / R=7 z normy ISO/TS 32003:2023. Używanym szyfrem jest AES-256-GCM z parametrami z NIST SP 800-38D. Dla każdego zaszyfrowanego obiektu układ transmisji składa się z 12-bajtowego wektora IV, szyfrogramu oraz 16-bajtowego znacznika uwierzytelniającego. Dodatkowe dane uwierzytelniane pozostają puste, zgodnie z wytycznymi profilu TS 32003 §5.2. Odszyfrowywanie weryfikuje znacznik i w przypadku niezgodności zgłasza TamperedDataException; nigdy nie zwraca tekstu jawnego po nieudanej weryfikacji znacznika. Ta ścieżka zapewnia wykrywanie modyfikacji, którego domyślna ścieżka CBC sama z siebie nie zapewnia.
Ścieżka GCM przestrzega zasady unikalności wektora IV opisanej w NIST SP 800-38D §8. Górne 4 bajty wektora IV stanowią pole stałe dla danego egzemplarza, ustawiane podczas konstrukcji z losowego źródła. Dolne 8 bajtów to licznik w porządku big-endian, który zwiększa się po każdym wydanym wektorze IV. Jest to zgodne z podejściem konstrukcji deterministycznej z §8.2.1, z tą różnicą, że pole stałe jest losowane, aby zapobiec kolizjom między dokumentami, zamiast być numerowane. Drugie zabezpieczenie rejestruje każdy wyemitowany wektor IV w zbiorze kolizji i zgłasza NonceReuseException, jeśli którakolwiek wartość się powtórzy. Przepełnienie licznika również zgłasza NonceReuseException, ponieważ jest to tryb awarii polegający na ponownym użyciu wektora IV, przed którym ostrzega §8.
Do ścieżki GCM mają zastosowanie dwa ograniczenia długości. Górny limit tekstu jawnego na obiekt wynosi 2^39 − 256 bajtów, czyli ograniczenie na pojedyncze wywołanie wyprowadzone z NIST SP 800-38D §5.2.1.1. Większe dane wejściowe powodują zgłoszenie wyjątku długości wraz ze wskazówką, aby podzielić dane na obiekty. Limit bezpieczeństwa wywołań wynosi 2^32 wywołań na klucz. assertWithinSafetyBound() to opcjonalne sprawdzenie, które zgłasza GcmInvocationLimitExceededException, pozwalając wywołującemu zmienić klucz dokumentu przed osiągnięciem progu z §8.3. NIST SP 800-57 część 1 §4 traktuje decyzję dotyczącą okresu życia klucza jako obowiązek wdrożeniowy.
Flagi uprawnień mają charakter zaleceń. Core zapisuje maskę bitową w zaszyfrowanym wpisie /Perms oraz w wartości /P, a następnie odzyskuje ją podczas odczytu za pomocą validatePerms(); w przypadku uszkodzonego znacznika ta walidacja kończy się odmową. Oczekuje się, że zgodny czytnik będzie respektował te flagi. Flagi te nie są egzekwowane kryptograficznie: procesor, który ma klucz odszyfrowujący i ignoruje te bity, może odczytać, skopiować lub zmodyfikować zawartość. Opisuj flagi uprawnień jako konwencję czytnika, a nie jako kontrolę dostępu.
Powierzchnia API
Dział zatytułowany „Powierzchnia API”| Typ | Rodzaj | Kluczowe składowe | Stabilność | Od wersji |
|---|---|---|---|---|
Aes256Encryptor | klasa | encrypt(), decrypt(), encryptForObject(), buildEncryptionDictionary(), verifyUserPassword(), verifyOwnerPassword(), validatePerms(), getEncryptionKey() | stabilny | 1.0.0 |
Aes256GcmEncryptor | klasa | encrypt(), decrypt(), encryptStream(), assertWithinSafetyBound(), invocationCount(), isAvailable() | stabilny | 2.18.0 |
KeyMaterial | klasa final readonly | generate(), exposeKey(), fingerprint() | stabilny | 2.18.0 |
EncryptedPayloadSpec | klasa final readonly | toDict() | stabilny | 2.18.0 |
CryptoCapabilities | klasa final | hasAesGcm(), detectFipsMode(), assertFipsAvailableForProfile() | stabilny | 2.0.0 |
NonceReuseException | wyjątek | — | stabilny | 2.18.0 |
TamperedDataException | wyjątek | — | stabilny | 2.18.0 |
DecryptionFailedException | wyjątek | — | stabilny | 2.18.0 |
GcmInvocationLimitExceededException | wyjątek | — | stabilny | 3.0.0 |
Przykład kodu — szybki start
Dział zatytułowany „Przykład kodu — szybki start”<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();
// AES-256-CBC, V=5/R=6. Call before addPage().$doc->setEncryption( userPassword: 'demo', ownerPassword: 'admin', permissions: 4, // printing only; copy/modify denied for a conforming reader);
$doc->addPage();$doc->setFont('helvetica', '', 12);$doc->cell(0, 8, 'Confidential', newLine: true);
$doc->save(__DIR__ . '/output/22-protection.pdf');Przykład kodu — produkcja
Dział zatytułowany „Przykład kodu — produkcja”<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Security\CryptoCapabilities;use NextPDF\Security\Encryption\Aes256GcmEncryptor;use NextPDF\Security\Exception\TamperedDataException;use NextPDF\Security\KeyMaterial;use Psr\Log\LoggerInterface;
final readonly class AuthenticatedBlobCipher{ public function __construct(private LoggerInterface $logger) {}
/** * Seal a payload with AES-256-GCM and return the wire-format bytes. * * @param non-empty-string $plaintext The payload to protect. * * @return non-empty-string IV(12) || ciphertext || tag(16). */ public function seal(string $plaintext, KeyMaterial $key): string { if (!CryptoCapabilities::hasAesGcm()) { throw new \RuntimeException('Host cannot perform AES-256-GCM.'); }
$cipher = new Aes256GcmEncryptor($key); // Opt-in NIST SP 800-38D §8.3 key-rotation guard. $cipher->assertWithinSafetyBound();
$wire = $cipher->encrypt($plaintext);
$this->logger->info('Payload sealed', [ 'key_fingerprint' => $key->fingerprint(), 'invocations' => $cipher->invocationCount(), ]);
return $wire; }
/** * Open a sealed payload; a modified payload raises, never returns plaintext. * * @param non-empty-string $wire IV(12) || ciphertext || tag(16). */ public function open(string $wire, KeyMaterial $key): string { try { return (new Aes256GcmEncryptor($key))->decrypt($wire); } catch (TamperedDataException $e) { $this->logger->warning('Tampered payload rejected', [ 'key_fingerprint' => $key->fingerprint(), ]);
throw $e; } }}Szyfr sprawdza możliwości hosta, stosuje opcjonalne zabezpieczenie wywołań, rejestruje wyłącznie nieodwracalny odcisk klucza i ponownie zgłasza odrzucenia wynikające z naruszenia integralności, zamiast zwracać podejrzane bajty.
Przypadki brzegowe i pułapki
Dział zatytułowany „Przypadki brzegowe i pułapki”- Domyślna ścieżka AES-256-CBC zapewnia wyłącznie poufność. Sama z siebie nie wykrywa zmodyfikowanego szyfrogramu. Gdy potrzebujesz wykrywania modyfikacji, użyj ścieżki AES-256-GCM.
useAesGcm()zgłasza wyjątek, gdy aktywny jest tryb PDF/A oraz gdy aniopenssl, aniext-sodiumnie oferuje AES-256-GCM. Przechwyć oba przypadki i przekaż operatorowi komunikat umożliwiający podjęcie działania.- Na hostach bez AES-NI libsodium odmawia wykonywania GCM. Core przełącza się na OpenSSL GCM, który jest poprawny, lecz wolniejszy; spada przepustowość, a nie bezpieczeństwo.
- Górny limit tekstu jawnego GCM na obiekt wynosi
2^39 − 256bajtów. Większe dane wejściowe powodują zgłoszenie wyjątku długości; podziel zawartość na wiele obiektów za pomocąencryptStream(). - Egzemplarz
KeyMaterialmusi mieć dokładnie 32 bajty. Konstruktor odrzuca błędną długość, zamiast ją skracać. - Ścieżka odczytu (
verifyUserPassword(),verifyOwnerPassword(),validatePerms()) używa porównania o stałym czasie wykonania dla materiału kryptograficznego i w przypadku uszkodzonego znacznika uprawnień kończy się odmową.
Wydajność
Dział zatytułowany „Wydajność”Szyfrowanie AES-256-CBC pojedynczego obiektu to jedno wywołanie OpenSSL o złożoności O(n) względem rozmiaru treści obiektu. Wyprowadzanie klucza uruchamia iterowaną procedurę Algorytmu 2.B raz na egzemplarz szyfratora; koszt jest ograniczony i stały na dokument. Strumieniowa ścieżka AES-256-GCM dzieli dane wejściowe na fragmenty po 16 MiB, ograniczając bieżące użycie sterty do około 64 MB niezależnie od całkowitego rozmiaru danych wejściowych i pozostając poniżej udokumentowanego limitu szczytowego 64 MB. Każdy obiekt GCM dodaje 28 bajtów narzutu (12-bajtowy wektor IV plus 16-bajtowy znacznik). Sprzęt AES-NI znacząco poprawia przepustowość GCM; bez niego spada jedynie przepustowość.
Uwagi dotyczące bezpieczeństwa
Dział zatytułowany „Uwagi dotyczące bezpieczeństwa”Ta powierzchnia szyfrowania ma jawny model zagrożeń. Normalizacja SASLprep wraz z iterowanym wyprowadzaniem klucza w wersji 6 podnosi koszt zgadywania hasła w trybie offline, jednak słabe hasło pozostaje dominującym ryzykiem szczątkowym. Żaden sposób wyprowadzania klucza nie usuwa tego ryzyka. Ścieżka GCM wykrywa modyfikację szyfrogramu dzięki weryfikacji znacznika; domyślna ścieżka CBC tego nie robi. W ścieżce GCM licznik wraz ze zbiorem kolizji zapobiega ponownemu użyciu wektora IV, zgodnie z zasadą dotyczącą IV z NIST SP 800-38D §8.1. Przepełnienie licznika powoduje odmowę, a nie zawinięcie. Maskowanie KeyMaterial oraz atrybut #[\SensitiveParameter] na hasłach ograniczają ujawnienie klucza poprzez dzienniki. Wyprowadzony materiał klucza jest zerowany po użyciu tam, gdzie pozwala na to platforma.
Granica również jest wyraźnie określona. Core stosuje szyfrowanie AES-256 zgodnie z definicją w ISO 32000-2:2020 §7.6, a dla ścieżki opcjonalnej zgodnie z ISO/TS 32003:2023 §5.2. Skuteczna ochrona zależy od siły hasła, zarządzania kluczami, środowiska wdrożeniowego oraz czytnika używanego do odczytu. Zgodne czytniki respektują flagi uprawnień, ale kryptografia ich nie egzekwuje. Krok AES-ECB użyty dla wartości /Perms jest wymagany przez ISO 32000-2:2020 §7.6.4.4.10 dla pojedynczego 16-bajtowego bloku. Nie jest to tryb ogólnego przeznaczenia. Core udostępnia sprawdzenie rotacji klucza przed osiągnięciem limitu 2^32 wywołań, ale domyślnie jej nie egzekwuje; ta rotacja jest obowiązkiem wdrożeniowym.
Rezydencja danych i ograniczanie ryzyka związanego z danymi osobowymi (PII)
Dział zatytułowany „Rezydencja danych i ograniczanie ryzyka związanego z danymi osobowymi (PII)”Szyfrowanie i odszyfrowywanie odbywają się w obrębie procesu; ta powierzchnia nie powoduje, że bajty dokumentu, hasło lub wartość klucza opuszczają hosta. Zbiór kolizji wektorów IV GCM jest indeksowany nieodwracalnym odciskiem klucza, a nie bajtami klucza. Jeśli wdrożenie umieszcza klucz za zewnętrznym systemem zarządzania kluczami lub tokenem PKCS#11, za rezydencję odpowiada to zaplecze; punktem kontraktowym dla generowania klucza rezydującego w tokenie jest OASIS PKCS#11 v3.1 C_GenerateKey.
Bezpieczna telemetria i czyszczenie dzienników
Dział zatytułowany „Bezpieczna telemetria i czyszczenie dzienników”Rejestruj nazwę polityki oraz 8-znakowy odcisk klucza, nigdy klucz ani hasło. KeyMaterial::__toString() oraz __debugInfo() zwracają zamaskowany symbol zastępczy. Wyjątki z tej powierzchni zawierają etykietę operacji oraz odcisk, a nie bajty klucza. Liczba wywołań GCM jest bezpieczną telemetrią dla pulpitów rotacji kluczy.
Model zagrożeń
Dział zatytułowany „Model zagrożeń”| Zagrożenie | Ograniczenie ryzyka w Core | Granica szczątkowa |
|---|---|---|
| Zgadywanie hasła w trybie offline | SASLprep wraz z iterowanym wyprowadzaniem klucza w wersji 6 | Słabe hasło wciąż pozostaje dominującym ryzykiem |
| Modyfikacja szyfrogramu | Weryfikacja znacznika GCM (ścieżka opcjonalna) | Ścieżka CBC zapewnia wyłącznie poufność |
| Ponowne użycie wektora IV (GCM) | Losowe pole stałe wraz z licznikiem i zbiorem kolizji; przepełnienie powoduje odmowę | — |
| Zbyt długi tekst jawny GCM | Sprawdzenie długości przy 2^39 − 256; wskazówka dotycząca podziału | Wywołujący musi strumieniować duże dane wejściowe |
| Nadmierne użycie klucza (GCM) | assertWithinSafetyBound() przy 2^32 | Opcjonalne; domyślnie nieegzekwowane |
| Obejście flag uprawnień | Brak — flagi mają charakter zaleceń | Niezgodny czytnik ignoruje flagi |
| Ujawnienie klucza poprzez dzienniki | Maskowanie KeyMaterial; #[\SensitiveParameter] | Wywołujący, który rejestruje exposeKey(), niweczy to zabezpieczenie |
Zachowanie w trybie FIPS
Dział zatytułowany „Zachowanie w trybie FIPS”Core nie jest modułem kryptograficznym walidowanym według FIPS i nie ma certyfikatu FIPS. CryptoCapabilities::detectFipsMode() to sonda o charakterze best-effort, która zgłasza stan aktywny, nieobecny lub nieokreślony. assertFipsAvailableForProfile() kończy się odmową, gdy profil FIPS zostanie wybrany na hoście, który nie potwierdza dostępności dostawcy FIPS. Powierzchnia szyfrowania działa w trybie zgodnym z FIPS, gdy uruchamiana jest na hoście z kompilacją OpenSSL, która załadowała dostawcę walidowanego według FIPS. Walidowana, certyfikowana konfiguracja jest kwestią edycji Enterprise.
Zgodność
Dział zatytułowany „Zgodność”| Twierdzenie | Standard | Klauzula | Dowód |
|---|---|---|---|
| Każdy wektor IV GCM jest unikalny w obrębie wywołania dzięki deterministycznej konstrukcji pole-stałe-plus-licznik. | NIST SP 800-38D | §8.2.1 | |
| Zasada konstrukcji wektora IV zapobiega ponownemu użyciu w obrębie wywołań na jednym kluczu. | NIST SP 800-38D | §8.1 | |
| Górny limit tekstu jawnego na obiekt odpowiada ograniczeniu długości na pojedyncze wywołanie. | NIST SP 800-38D | §5.2.1.1 | |
| Okres życia klucza i jego rotacja są obowiązkiem wdrożeniowym. | NIST SP 800-57 część 1 wyd. 5 | §4 | |
| Klucz pliku AES ma 256 bitów, co odpowiada długości klucza określonej w standardzie. | FIPS 197 | §4.2.1 | |
| Generowanie klucza rezydującego w tokenie jest punktem integracji z zewnętrznym magazynem kluczy. | OASIS PKCS#11 v3.1 | C_GenerateKey |
ISO 32000-2:2020 §7.6 oraz ISO/TS 32003:2023 §5.2 stanowią normatywną podstawę dla programów obsługi udokumentowanych tutaj. Ich tekst jest objęty ograniczeniami licencyjnymi. Ta strona parafrazuje te standardy, cytuje klauzule po numerach i nie przytacza żadnego z nich dosłownie. Test zgodności Algorytmu 2.B oraz fikstura zewnętrznego oracle wskazane w stopce dowodowej strony dostarczają zweryfikowanych dowodów wykonania dla bajtowo dokładnego wyprowadzania klucza.
Kontekst komercyjny
Dział zatytułowany „Kontekst komercyjny”Core dostarcza domyślną ścieżkę AES-256-CBC, opcjonalną ścieżkę AES-256-GCM, powierzchnię klucza lokalnego oraz bramkę polityki kryptograficznej. Edycja Enterprise dodaje zaplecze przechowywania kluczy HSM/PKCS#11 oraz profil polityki kryptograficznej w trybie FIPS w obrębie tych samych kontraktów. Publiczne API jest identyczne; różni się zaplecze przechowywania kluczy oraz implementacja polityki.
Zobacz też
Dział zatytułowany „Zobacz też”- Zabezpieczenia — przegląd modułu zabezpieczeń oraz granica uprawnień.
- Kontrakty / Polityka zabezpieczeń — kontrakt polityki kryptograficznej, który steruje szyfrem.
- Zabezpieczenia / Podpisywanie — podpisy i znaczniki czasu, pokrewna powierzchnia kryptograficzna.
- Zgodność — zakaz stosowania klucza
Encryptw PDF/A.