Lewati ke konten

Keamanan / Penandatanganan: CMS, stempel waktu RFC 3161, LTV, dan kepercayaan

Halaman ini menjelaskan permukaan penandatanganan di NextPDF Core: menghasilkan tanda tangan Content Management Syntax (CMS), menerapkan stempel waktu Request for Comments (RFC) 3161, memvalidasi rantai sertifikat terhadap RFC 5280, dan memeriksa pencabutan melalui Online Certificate Status Protocol (OCSP) serta daftar pencabutan sertifikat (CRL). Pembahasannya tetap berada pada tingkat perilaku. Kelas implementasi Core bersifat internal: kode produksi menggunakan kontrak SignerInterface, bukan tipe konkret NextPDF\Security\Signature. Verifikator, bersama trust anchor yang dikonfigurasikannya, menentukan apakah tanda tangan yang dihasilkan terverifikasi. Hasil tersebut berada di luar kendali produsen, dan halaman ini menyatakannya di setiap tempat yang relevan.

Terminal window
composer require nextpdf/core:^3

Core membangun struktur CMS SignedData dari rentang byte, lalu menyimpannya di entri Contents kamus tanda tangan sebagai data yang dienkode dengan Distinguished Encoding Rules (DER) — ISO 32000-2 §12.8.1. Struktur tersebut membawa atribut bertanda tangan pada SignerInfo, termasuk content-type dan message-digest — RFC 5652 §5.3. Verifikator menghitung ulang digest konten dan membandingkannya dengan atribut message-digest. Nilainya harus cocok agar tanda tangan valid — RFC 5652 §5.4. SignerInfo juga membawa pengenal algoritma digest dan blok atribut bertanda tangan — RFC 5652 §5. Core menggunakan phpseclib3 untuk jalur penandatanganan perangkat lunak bawaan: RSA, RSASSA-PSS, ECDSA, dan Ed25519.

Stempel waktu RFC 3161 adalah pertukaran permintaan dan respons dengan Time-Stamping Authority (TSA) yang mengembalikan struktur TSTInfo — RFC 3161 §2.4.1. Setiap token membawa serialNumber yang unik untuk TSA penerbit — RFC 3161 §2.4.2 — dan genTime yang dinyatakan dalam Coordinated Universal Time (UTC), yaitu waktu token dibuat — RFC 3161 §2.4.2.

Validasi kepercayaan mencakup dua pemeriksaan. Validasi jalur menelusuri jalur dari sertifikat penanda tangan hingga trust anchor, serta memeriksa basic constraints dan masukan pembentukan jalur — RFC 5280 §6.1. Pemeriksaan pencabutan menanyakan responder OCSP atau membaca CRL: respons OCSP melaporkan good, revoked, atau unknown — RFC 6960 §2.2 — dan thisUpdate serta nextUpdate pada respons tersebut membatasi tingkat kemutakhiran status itu — RFC 6960 §4.2. Pemanggil menyediakan trust anchor dan kebijakan kesegaran pencabutan. Mesin memvalidasi berdasarkan masukan tersebut dan tidak menyertakan daftar kepercayaan bawaan.

TipeJenisPeranStabilitasSejak
SignerInterfaceantarmuka (NextPDF\Contracts)Kontrak penandatanganan yang diandalkan pemanggilstabil1.0.0
SignatureLevelenumPemilih level dan probe ketersediaan PDF Advanced Electronic Signatures (PAdES)stabil1.0.0
Rfc5280PathValidatorantarmukaTitik masuk validasi jalur sertifikasi (validate(...))stabil (dibekukan 3.1.0)3.1.0
RevocationStatusenumOCSP / CRL outcome: good, revoked, unknownstabil3.1.0
CaTrustAnchorBundletipeKumpulan trust anchor yang disediakan pemanggilstabil3.1.0
TstInfotipeField stempel waktu RFC 3161 yang telah diuraistabil3.2.0

SignerInterface::sign() mengembalikan sebuah SignatureResult. Metode toHex() pada objek tersebut menghasilkan string heksadesimal /Contents, dan properti cmsSignedData menyimpan byte DER mentah. Kelas konkret NextPDF\Security\Signature yang mengimplementasikan perilaku ini bersifat internal (stability: internal di manifes modul). Kelas tersebut bukan bagian dari API publik dan dapat berubah tanpa kenaikan versi mayor. Bersandarlah pada kontrak dan enum di atas.

examples/contracts/signing-quickstart.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\SignerInterface;
/**
* Produce the CMS SignedData hex for a PDF /Contents field.
*
* @param SignerInterface $signer A Core or Premium signer.
* @param string $byteRange The PDF byte range to sign.
*
* @return string Hex-encoded CMS SignedData.
*/
function sign(SignerInterface $signer, string $byteRange): string
{
return $signer->sign($byteRange)->toHex();
}

Pemanggil bergantung pada kontrak. Penanda tangan perangkat lunak Core dan penanda tangan Hardware Security Module (HSM) Premium sama-sama memenuhi SignerInterface, sehingga kode ini tidak berubah antar-edisi.

examples/contracts/signing-trust.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\SignerInterface;
use NextPDF\Contracts\TimestampProviderInterface;
use NextPDF\Exception\NextPdfException;
use Psr\Log\LoggerInterface;
final readonly class TimestampedSigner
{
public function __construct(
private SignerInterface $signer,
private TimestampProviderInterface $timestamps,
private LoggerInterface $logger,
) {}
/**
* Sign a byte range, then timestamp the CMS structure.
*
* The timestamp's trust still depends on the verifier accepting the
* Time-Stamping Authority; this method only produces the structure.
*
* @param string $byteRange The PDF byte range to sign.
*
* @return array{cms: string, tst: string}
*/
public function sign(string $byteRange): array
{
try {
$signature = $this->signer->sign($byteRange);
$token = $this->timestamps->getTimestamp($signature->cmsSignedData);
return ['cms' => $signature->toHex(), 'tst' => $token];
} catch (NextPdfException $e) {
$this->logger->error('Signing failed', ['error' => $e->getMessage()]);
throw $e;
}
}
}

Penyedia stempel waktu disuntikkan agar suatu penerapan dapat menetapkan Time-Stamping Authority-nya sendiri. Blok catch mencatat dan melempar ulang. Blok tersebut tidak pernah menyembunyikan kegagalan, sehingga jalur penandatanganan tetap fail-closed.

  • Tanda tangan yang dihasilkan bukanlah tanda tangan yang terverifikasi. Validasi jalur dan pencabutan berjalan di verifikator, menggunakan trust anchor milik verifikator tersebut. Produsen tidak dapat menegaskan hasilnya.
  • Digest rentang byte tidak menyertakan nilai tanda tangan. Digest yang mencakup oktet Contents tidak dapat diverifikasi — ISO 32000-2 §12.8.1.
  • Status pencabutan memiliki jendela kesegaran. Respons OCSP hanya mutakhir dalam interval thisUpdate / nextUpdate-nya — RFC 6960 §4.2. Respons usang bukanlah pengganti pemeriksaan terbaru pada saat validasi.
  • Mesin tidak menyertakan daftar kepercayaan bawaan. CaTrustAnchorBundle disediakan pemanggil; bundel kosong berarti tidak ada rantai yang tervalidasi, sesuai rancangan.
  • OCSP unknown bukanlah good. Perlakukan unknown sebagai ketiadaan penetapan, bukan kelulusan implisit — RFC 6960 §2.2.
  • Penyimpanan kunci HSM, penandatanganan tertunda dan cloud, serta produsen PAdES B-LT / B-LTA tidak ada di Core. Memilih jalur tersebut pada distribusi Core akan gagal secara fail-closed dengan pesan yang menyebutkan komponen Enterprise yang hilang.

Penandatanganan perangkat lunak biasanya memerlukan beberapa milidetik saja. Stempel waktu menambah satu perjalanan bolak-balik jaringan ke TSA. Validasi jalur bersifat lokal setelah sertifikat berada di memori; pencabutan menambah satu pengambilan OCSP atau CRL per sertifikat dalam rantai. Anggaran wall 1500 ms mencakup satu tanda tangan berstempel waktu dengan TSA jarak jauh pada koneksi hangat. Pemeriksaan pencabutan terhadap endpoint yang lambat melampaui anggaran tersebut dan seharusnya berada di luar jalur permintaan. Profil reproduksibilitas adalah structural: stempel waktu menyematkan saat penandatanganan, sehingga dua eksekusinya berbeda pada byte stempel waktu sementara struktur dokumen tetap identik.

Ini adalah batas kriptografis utama mesin, sehingga model ancamannya dibuat eksplisit. Mesin menghitung rentang byte dan tidak pernah menerimanya dari pemanggil. Jalur penandatanganan bersifat fail-closed: kegagalan primitif atau kesenjangan kapabilitas menghasilkan eksepsi bertipe dan tidak pernah diam-diam turun ke algoritma yang lebih lemah. Pada level yang mewajibkan stempel waktu (B-T, B-LT, B-LTA), Time-Stamping Authority yang mengembalikan token kosong adalah kesalahan terminal: tanda tangan ditolak, bukan dihasilkan dalam keadaan tanpa stempel yang levelnya diam-diam diturunkan, kecuali ada penangan kesalahan yang dipasang untuk mengizinkan degradasi terdokumentasi. Kepercayaan dikendalikan pemanggil sesuai rancangan: anchor dan kebijakan pencabutan adalah masukan, bukan bawaan mesin, karena produsen yang menegaskan kepercayaannya sendiri akan menegaskan fakta yang hanya dapat ditetapkan oleh verifikator. Kepercayaan stempel waktu pada akhirnya bergantung pada Time-Stamping Authority, yang dapat disuntikkan sehingga suatu penerapan dapat menetapkan miliknya sendiri. Halaman ini ditandai export_control_class: legal-review-required karena berkaitan dengan penandatanganan kriptografis; setiap sumber normatif diparafrasekan dan tidak ada yang direproduksi, sesuai higiene kutipan.

KlaimStandarKlausulBukti
Tanda tangan CMS disimpan sebagai data yang dienkode DER di entri Contents kamus tanda tangan.ISO 32000-2§12.8.1
SignerInfo membawa atribut bertanda tangan berupa content-type dan message-digest.RFC 5652§5.3
Verifikator menghitung ulang digest konten dan membandingkannya dengan atribut message-digest.RFC 5652§5.4
Token stempel waktu dihasilkan oleh RFC 3161 TSA dan membawa serialNumber yang unik serta genTime UTC.RFC 3161§2.4.1, §2.4.2,,
Validasi jalur sertifikasi memeriksa basic constraints dan masukan jalur dari penanda tangan menuju trust anchor.RFC 5280§6.1,
OCSP melaporkan certStatus sebagai good, revoked, atau unknown, dibatasi oleh thisUpdate / nextUpdate.RFC 6960§2.2, §4.2,

Semua klausul diparafrasekan. NextPDF tidak mereproduksi teks normatif. Rujuk standar yang diterbitkan untuk redaksi otoritatifnya.

Core menyertakan penanda tangan perangkat lunak CMS (RSA, RSASSA-PSS, ECDSA, Ed25519), konsumsi stempel waktu RFC 3161, validasi jalur RFC 5280, dan pemeriksaan pencabutan OCSP / CRL. Penyimpanan kunci HSM dan Public-Key Cryptography Standards #11 (PKCS#11), penandatanganan tertunda dan cloud, produsen PAdES B-LT dan B-LTA, serta profil kebijakan-kripto Federal Information Processing Standards (FIPS) 140-3 disertakan dalam edisi Pro dan Enterprise. Core menyelesaikan hal ini pada runtime melalui kontrak, sehingga mesin sumber terbuka tidak membawa dependensi komersial, dan API tidak berubah saat pemutakhiran.