İçeriğe geç

Şifreleme: AES-256 (CBC) ve AES-256-GCM

Core, Taşınabilir Belge Biçimi (PDF) dosyalarını ISO 32000-2:2020 §7.6 standart güvenlik işleyicisi kapsamında AES-256 (256 bit anahtarlı Gelişmiş Şifreleme Standardı) ile şifreler. Varsayılan kip, V=5 / R=6 / AESV3 (AES-256-CBC, Şifre Blok Zincirleme) kipidir. İsteğe bağlı kimlik doğrulamalı kip ise ISO/TS 32003:2023 V=6 / R=7 AES-256-GCM (Galois/Sayaç Kipi) yoludur. Bu sayfa anahtar türetmeyi, aktarım biçimini, izin sınırını ve dağıtım sınırlarını tanımlar.

Terminal window
composer require nextpdf/core:^3

Varsayılan yol openssl uzantısını gerektirir. AES-256-GCM yolu openssl veya ext-sodium kullanır. AES-NI donanımı bulunmayan ana makinelerde libsodium GCM’yi reddeder; Core, algoritmayı değiştirmeden daha yavaş olan OpenSSL uygulamasına geri döner.

Varsayılan işleyici, AESV3 şifreleme süzgeciyle V=5 / R=6 standart güvenlik işleyicisini kullanır. setEncryption() çağrıldığında Core, platformun kriptografik rastgelelik kaynağından (random_bytes()) rastgele bir 256 bit dosya anahtarı üretir. Anahtar 32 bayttır ve FIPS 197 anahtar uzunluğuyla eşleşir. Core, her nesnenin içeriğini AES-256-CBC ile şifreler. ISO 32000-2:2020 §7.6.4 uyarınca 16 baytlık başlatma vektörünü her şifreli metnin önüne ekler.

Anahtar türetme, Revizyon 6’da Algoritma 2.B yöntemini izler. Core önce parolayı SASLprep (RFC 4013) ile normalleştirir, ardından ISO 32000-2:2020 §7.6.4.3.3 uyarınca karakter sınırını koruyarak 127 UTF-8 bayta kısaltır. Türetilmiş özeti, bir AES-128-CBC adımıyla yürütülen yinelemeli bir SHA-256 / SHA-384 / SHA-512 yordamıyla hesaplar; bu, çevrimdışı parola tahmininin maliyetini artırır. Core; kullanıcı, sahip ve anahtar tuzlarını her şifreleyici örneği için bir kez üretir. Böylece bir örnek belirlenimci sözlük baytları yayar; bu, çok geçişli bir yazıcı için ön koşuldur.

useAesGcm() isteğe bağlı AES-256-GCM yolunu etkinleştirir. ISO/TS 32003:2023 V=6 / R=7 AESV4 şifreleme süzgecini uygular. Şifre, parametreleri NIST SP 800-38D belgesinden alınan AES-256-GCM’dir. Şifrelenen her nesne için aktarım düzeni, 12 baytlık bir IV, şifreli metin ve 16 baytlık bir kimlik doğrulama etiketinden oluşur. TS 32003 §5.2 profilinin yönlendirdiği üzere ek kimlik doğrulamalı veri boştur. Şifre çözme, etiketi doğrular ve uyuşmazlık durumunda TamperedDataException fırlatır; başarısız bir etiketten sonra asla düz metin döndürmez. Bu yol, varsayılan CBC yolunun tek başına sağlamadığı değişiklik algılamayı ekler.

GCM yolu, NIST SP 800-38D §8’deki IV benzersizliği ilkesini izler. IV’nin üst 4 baytı, oluşturma sırasında rastgele bir kaynakla ayarlanan örnek başına sabit bir alandır. Alt 8 bayt, yayımlanan her IV’den sonra artan büyük uçlu (big-endian) bir sayaçtır. Bu, §8.2.1’deki belirlenimci oluşturma yaklaşımını izler; ancak sabit alan, sıralı atanmak yerine belgeler arası çakışmaları önlemek üzere rastgeleleştirilir. İkinci koruma olarak, yayılan her IV bir çakışma kümesine kaydedilir ve bir değer yinelenirse NonceReuseException fırlatılır. Sayaç taşması da NonceReuseException fırlatır; çünkü taşma, §8’in karşı uyardığı IV yeniden kullanım hatası kipidir.

GCM yolunda iki sınır uygulanır. Nesne başına düz metin tavanı 2^39 − 256 bayttır; bu, NIST SP 800-38D §5.2.1.1 bölümünde türetilen çağrı başına sınırdır. Daha büyük girdi, verileri nesnelere bölüştürme yönergesiyle bir uzunluk istisnası fırlatır. Çağrı güvenliği sınırı, anahtar başına 2^32 çağrıdır. assertWithinSafetyBound(), GcmInvocationLimitExceededException fırlatan isteğe bağlı bir denetimdir; çağıranın §8.3 eşiğinden önce belge anahtarını döndürmesine olanak tanır. NIST SP 800-57 Bölüm 1 §4, bu anahtar ömrü kararını bir dağıtım sorumluluğu olarak ele alır.

İzin bayrakları yalnızca yönlendirici niteliktedir. Core, bit maskesini şifreli /Perms girdisine ve /P değerine yazar, ardından okuma sırasında bunu, bozuk bir imleçte güvenli biçimde kapanan validatePerms() ile kurtarır. Uyumlu bir okuyucunun bayraklara uyması beklenir. Bayraklar kriptografik olarak zorlanmaz: şifre çözme anahtarına sahip olup bitleri yok sayan bir işlemci içeriği okuyabilir, kopyalayabilir veya değiştirebilir. İzin bayraklarını bir erişim denetimi olarak değil, bir okuyucu kuralı olarak değerlendirin.

TürÇeşitAnahtar üyelerKararlılıkBu sürümden beri
Aes256Encryptorsınıfencrypt(), decrypt(), encryptForObject(), buildEncryptionDictionary(), verifyUserPassword(), verifyOwnerPassword(), validatePerms(), getEncryptionKey()kararlı1.0.0
Aes256GcmEncryptorsınıfencrypt(), decrypt(), encryptStream(), assertWithinSafetyBound(), invocationCount(), isAvailable()kararlı2.18.0
KeyMaterialfinal readonly sınıfgenerate(), exposeKey(), fingerprint()kararlı2.18.0
EncryptedPayloadSpecfinal readonly sınıftoDict()kararlı2.18.0
CryptoCapabilitiesfinal sınıfhasAesGcm(), detectFipsMode(), assertFipsAvailableForProfile()kararlı2.0.0
NonceReuseExceptionistisnakararlı2.18.0
TamperedDataExceptionistisnakararlı2.18.0
DecryptionFailedExceptionistisnakararlı2.18.0
GcmInvocationLimitExceededExceptionistisnakararlı3.0.0
examples/22-protection.php
<?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');
examples/security/gcm-authenticated-encryption.php
<?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;
}
}
}

Şifreleyici, ana makine yeteneğini denetler, isteğe bağlı çağrı korumasını uygular, yalnızca geri döndürülemez anahtar parmak izini günlüğe kaydeder ve kuşkulu baytları döndürmek yerine kurcalama reddi istisnalarını yeniden fırlatır.

  • Varsayılan AES-256-CBC yolu yalnızca gizlilik sağlar. Tek başına değiştirilmiş şifreli metni algılamaz. Değişiklik algılamaya ihtiyaç duyduğunuzda AES-256-GCM yolunu kullanın.
  • useAesGcm(), PDF/A kipi etkin olduğunda ve ne openssl ne de ext-sodium AES-256-GCM sunmadığında fırlatır. Her iki durumu da yakalayın ve operatörün eyleme geçebileceği bir ileti gösterin.
  • AES-NI bulunmayan ana makinelerde libsodium GCM’yi reddeder. Core, doğru ancak daha yavaş olan OpenSSL GCM’ye geri döner; güvenlik değil, çıktı hızı düşer.
  • GCM nesne başına düz metin tavanı 2^39 − 256 bayttır. Daha büyük girdi bir uzunluk istisnası fırlatır; içeriği encryptStream() ile birden çok nesneye bölüştürün.
  • Bir KeyMaterial örneği tam olarak 32 bayt olmalıdır. Oluşturma, yanlış bir uzunluğu kısaltmak yerine reddeder.
  • Okuyucu yolu (verifyUserPassword(), verifyOwnerPassword(), validatePerms()) kriptografik malzeme için sabit zamanlı karşılaştırma kullanır ve bozuk bir izin imleciyle karşılaştığında güvenli biçimde kapanır.

Nesne başına AES-256-CBC şifrelemesi tek bir OpenSSL çağrısıdır ve nesne gövdesinde O(n)‘dir. Anahtar türetme, yinelemeli Algoritma 2.B yordamını çalıştırır; yordam şifreleyici örneği başına bir kez çalışır, bu nedenle maliyet sınırlıdır ve belge başına sabittir. AES-256-GCM akış yolu, girdiyi 16 MiB’lik parçalara böler; bu, canlı yığın kullanımını toplam girdi boyutundan bağımsız olarak yaklaşık 64 MB ile sınırlar ve belgelenen 64 MB tepe bütçesinin altında kalır. Her GCM nesnesi 28 bayt ek yük ekler (12 baytlık IV artı 16 baytlık etiket). AES-NI donanımı GCM çıktı hızını belirgin biçimde iyileştirir; bunsuz yalnızca çıktı hızı düşer.

Bu şifreleme yüzeyinin açık bir tehdit modeli vardır. SASLprep normalleştirmesi artı yinelemeli revizyon-6 anahtar türetmesi, çevrimdışı parola tahmininin maliyetini artırır; ancak zayıf bir parola, baskın artık risk olmaya devam eder. Hiçbir türetme bu riski ortadan kaldırmaz. GCM yolu, etiket doğrulaması yoluyla şifreli metin değişikliğini algılar; varsayılan CBC yolu ise bunu algılamaz. GCM yolunda sayaç ve çakışma kümesi, NIST SP 800-38D §8.1 IV ilkesiyle tutarlı biçimde IV yeniden kullanımını önler. Sayaç taşması, başa sarmak yerine reddeder. KeyMaterial karartması ve parolalardaki #[\SensitiveParameter] özniteliği, günlükler aracılığıyla anahtar açığa çıkmasını azaltır. Türetilmiş anahtar malzemesi, platformun izin verdiği yerlerde kullanımdan sonra sıfırlanır.

Sınır da nettir. Core, AES-256 şifrelemesini ISO 32000-2:2020 §7.6 ve isteğe bağlı yol için ISO/TS 32003:2023 §5.2 bölümünde tanımlandığı biçimde uygular. Etkin koruma; parola gücüne, anahtar yönetimine, dağıtım ortamına ve tüketici okuyucuya bağlıdır. Uyumlu okuyucular izin bayraklarına uyar, ancak kriptografi bunları zorlamaz. /Perms değeri için kullanılan AES-ECB adımı, tek bir 16 baytlık blok için ISO 32000-2:2020 §7.6.4.4.10 tarafından zorunlu kılınır. Bu, genel amaçlı bir kip değildir. Core, 2^32 çağrı sınırından önce anahtar döndürme için bir denetim sunar, ancak bunu varsayılan olarak zorlamaz; bu döndürme bir dağıtım sorumluluğudur.

Şifreleme ve şifre çözme süreç içinde çalışır; bu yüzey aracılığıyla hiçbir belge baytı, parola veya anahtar değeri ana makineden ayrılmaz. GCM IV çakışma kümesi, anahtar baytlarına değil, geri döndürülemez bir anahtar parmak izine göre anahtarlanır. Bir dağıtım, anahtarı bir dış anahtar-yönetim sisteminin veya bir PKCS#11 belirtecinin arkasına yerleştirirse, yerleşimden o arka uç sorumludur; OASIS PKCS#11 v3.1 C_GenerateKey, belirteç-yerleşik anahtar üretimi için sözleşme noktasıdır.

Politika adını ve 8 karakterlik anahtar parmak izini günlüğe kaydedin, anahtarı veya parolayı asla kaydetmeyin. KeyMaterial::__toString() ve __debugInfo() karartılmış bir yer tutucu döndürür. Bu yüzeyden gelen istisnalar, anahtar baytları değil, bir işlem etiketi ve bir parmak izi içerir. GCM çağrı sayısı, anahtar döndürme panoları için güvenli telemetridir.

TehditCore’daki azaltmaArtık sınır
Çevrimdışı parola tahminiSASLprep artı yinelemeli revizyon-6 türetmesiZayıf bir parola hâlâ baskın risktir
Şifreli metin değişikliğiGCM etiket doğrulaması (isteğe bağlı yol)CBC yolu yalnızca gizlilik sağlar
IV yeniden kullanımı (GCM)Rastgele sabit alan artı sayaç artı çakışma kümesi; taşma reddeder
Aşırı uzun GCM düz metniUzunluk denetimi 2^39 − 256 değerinde; bölüştürme yönergesiÇağıran, büyük girdiyi akışla işlemelidir
Anahtarın aşırı kullanımı (GCM)assertWithinSafetyBound(), sınır 2^32İsteğe bağlı; varsayılan olarak zorlanmaz
İzin-bayrağı atlatmasıYok — bayraklar yönlendiricidirUyumsuz bir okuyucu bayrakları yok sayar
Günlükler aracılığıyla anahtar açığa çıkmasıKeyMaterial karartması; #[\SensitiveParameter]Bir çağıran exposeKey() çıktısını günlüğe kaydederse bunu etkisiz kılar

Core, FIPS doğrulamalı bir kriptografik modül değildir ve FIPS sertifikalı değildir. CryptoCapabilities::detectFipsMode(), etkin, yok veya belirsiz sonucunu bildiren en iyi çaba yoklamasıdır. assertFipsAvailableForProfile(), bir FIPS sağlayıcısını kanıtlamayan bir ana makinede bir FIPS profili seçildiğinde güvenli biçimde kapanır. Şifreleme yüzeyi, FIPS doğrulamalı bir sağlayıcının yüklü olduğu bir ana makine OpenSSL derlemesine karşı çalıştığında FIPS uyumlu bir kipte çalışır. Doğrulanmış, sertifikalı bir duruş bir Enterprise konusudur.

İddiaStandartMaddeKanıt
Her GCM IV’si, belirlenimci bir sabit-alan-artı-sayaç oluşturma yoluyla çağrı başına benzersizdir.NIST SP 800-38D§8.2.1
IV oluşturma ilkesi, bir anahtarda çağrılar arası yeniden kullanımı önler.NIST SP 800-38D§8.1
Nesne başına düz metin tavanı, çağrı başına uzunluk sınırıyla eşleşir.NIST SP 800-38D§5.2.1.1
Anahtar kripto-dönemi ve döndürmesi bir dağıtım sorumluluğudur.NIST SP 800-57 Bölüm 1 Rev. 5§4
AES dosya anahtarı 256 bittir ve standardın anahtar uzunluğuyla eşleşir.FIPS 197§4.2.1
Belirteç-yerleşik anahtar üretimi, dış anahtar-deposu tümleştirme noktasıdır.OASIS PKCS#11 v3.1C_GenerateKey

ISO 32000-2:2020 §7.6 ve ISO/TS 32003:2023 §5.2, burada belgelenen işleyiciler için normatif temeldir. Metinleri lisansla kısıtlanmıştır. Bu sayfa, o standartları başka sözcüklerle anlatır, maddeleri numarayla anar ve hiçbirinden alıntı yapmaz. Algoritma 2.B standartlar testi ve sayfanın kanıt fragmanındaki dış tahkim test düzeneği, bayt düzeyinde eşleşen anahtar türetmesi için doğrulanmış çalışma zamanı kanıtı sağlar.

Core, varsayılan AES-256-CBC yolunu, isteğe bağlı AES-256-GCM yolunu, yerel anahtar yüzeyini ve kripto-politika kapısını sunar. Enterprise sürümü, aynı sözleşmelerin arkasında bir HSM/PKCS#11 anahtar saklama arka ucu ve bir FIPS kipi kripto-politika profili ekler. Public API aynıdır; anahtar saklama arka ucu ve politika uygulaması farklıdır.