Salta ai contenuti

Sicurezza / firma: CMS, marca temporale RFC 3161, LTV e attendibilità

Questa pagina descrive la superficie di firma fornita da NextPDF Core: produzione di una firma CMS, applicazione di una marca temporale RFC 3161, convalida di una catena di certificati rispetto a RFC 5280 e verifica della revoca tramite OCSP e CRL. Il livello è comportamentale. Le classi di implementazione di Core sono interne: il codice di produzione utilizza il contratto SignerInterface, non i tipi concreti NextPDF\Security\Signature. Che una firma prodotta venga verificata dipende dal verificatore e dagli anchor di attendibilità con cui è configurato. Tale esito resta al di fuori del controllo del produttore e questa pagina lo dichiara ovunque sia rilevante.

Terminal window
composer require nextpdf/core:^3

Core costruisce una struttura CMS SignedData a partire dall’intervallo di byte e la memorizza in codifica DER nella voce Contents del dizionario della firma — ISO 32000-2 §12.8.1. La struttura trasporta gli attributi firmati di SignerInfo — tra cui content-type e message-digest — RFC 5652 §5.3. Un verificatore ricalcola il digest del contenuto e lo confronta con l’attributo message-digest. Il confronto deve avere esito positivo affinché la firma sia valida — RFC 5652 §5.4. Il SignerInfo trasporta inoltre l’identificatore dell’algoritmo di digest e il blocco degli attributi firmati — RFC 5652 §5. Core firma tramite phpseclib3 per i percorsi software forniti: RSA, RSASSA-PSS, ECDSA ed Ed25519.

Una marca temporale RFC 3161 prevede uno scambio richiesta-risposta con una Time-Stamping Authority che restituisce una struttura TSTInfo — RFC 3161 §2.4.1. Ogni token trasporta un serialNumber univoco per la TSA emittente — RFC 3161 §2.4.2 — e un genTime espresso in UTC, l’istante in cui il token è stato creato — RFC 3161 §2.4.2.

La convalida dell’attendibilità si compone di due controlli. La convalida del percorso procede dal certificato del firmatario fino a un anchor di attendibilità, verificando i vincoli di base e gli input di costruzione del percorso — RFC 5280 §6.1. Il controllo della revoca interroga un responder OCSP oppure legge una CRL: una risposta OCSP segnala good, revoked o unknown — RFC 6960 §2.2 — e i campi thisUpdate e nextUpdate della risposta delimitano la freschezza di tale stato — RFC 6960 §4.2. Gli anchor di attendibilità e i criteri di aggiornamento della revoca sono forniti dal chiamante. Il motore convalida in base a ciò che gli viene fornito e non include un elenco di attendibilità integrato.

TipoGenereRuoloStabilitàDa
SignerInterfaceinterface (NextPDF\Contracts)Contratto di firma da cui dipendono i chiamantistabile1.0.0
SignatureLevelenumSelettore del livello PAdES e sonda di disponibilitàstabile1.0.0
Rfc5280PathValidatorinterfacePunto di ingresso per la convalida del percorso di certificazione (validate(...))stabile (congelata in 3.1.0)3.1.0
RevocationStatusenumEsito OCSP / CRL: good, revoked, unknownstabile3.1.0
CaTrustAnchorBundletypeInsieme di anchor di attendibilità fornito dal chiamantestabile3.1.0
TstInfotypeCampi della marca temporale RFC 3161 analizzatistabile3.2.0

SignerInterface::sign() restituisce un SignatureResult: toHex() produce la stringa esadecimale di /Contents e la proprietà cmsSignedData contiene i byte DER grezzi. Le classi concrete NextPDF\Security\Signature che implementano questi comportamenti sono interne (stability: internal nel manifest del modulo); non fanno parte dell’API pubblica e possono cambiare senza un incremento di versione maggiore. Dipendere dai contratti e dagli enum indicati sopra.

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();
}

Il chiamante dipende dal contratto: sia un signer software di Core sia un signer HSM Premium soddisfano SignerInterface, quindi questo codice resta invariato tra le edizioni.

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;
}
}
}

Il provider di marche temporali viene iniettato affinché una distribuzione vincoli la propria Time-Stamping Authority. Il blocco catch registra l’eccezione e la rilancia. Non assorbe mai l’errore: il percorso di firma resta fail-closed.

  • Una firma prodotta non è una firma verificata. La convalida del percorso e la revoca vengono eseguite dal verificatore, con gli anchor di attendibilità del verificatore stesso. Il produttore non può asserirne l’esito.
  • Il digest dell’intervallo di byte esclude il valore della firma. Un digest che copre gli ottetti di Contents non può essere verificato — ISO 32000-2 §12.8.1.
  • Lo stato di revoca ha una finestra di aggiornamento. Una risposta OCSP è aggiornata soltanto entro il proprio intervallo thisUpdate / nextUpdate — RFC 6960 §4.2. Una risposta obsoleta non sostituisce un controllo aggiornato al momento della convalida.
  • Il motore non include alcun elenco di attendibilità integrato. CaTrustAnchorBundle è fornito dal chiamante; un bundle vuoto significa che nessuna catena viene convalidata, per progettazione.
  • OCSP unknown non è good. Trattare unknown come esito indeterminato, non come un esito positivo implicito — RFC 6960 §2.2.
  • La custodia delle chiavi HSM, la firma differita e nel cloud e il produttore PAdES B-LT / B-LTA non sono presenti in Core. Nella distribuzione Core, la selezione di tali percorsi fallisce in modo fail-closed con un messaggio che indica il componente Enterprise mancante.

Una firma software richiede pochi millisecondi, nell’ordine delle unità. Una marca temporale aggiunge un round trip di rete verso la TSA. La convalida del percorso è locale una volta che i certificati sono in memoria; la revoca aggiunge un recupero OCSP o CRL per ogni certificato nella catena. Il budget di 1500 ms di tempo reale copre una singola firma con marca temporale, usando una TSA remota su una connessione già attiva. La revoca verso un endpoint lento supera tale budget e va collocata al di fuori del percorso della richiesta. Il profilo di riproducibilità è structural: una marca temporale incorpora l’istante di firma, perciò due esecuzioni differiscono nei byte della marca temporale mentre la struttura del documento resta identica.

Questo è il confine crittografico primario del motore, quindi il modello delle minacce è esplicito. L’intervallo di byte è calcolato dal motore e non viene mai accettato dal chiamante. Il percorso di firma è fail-closed: il fallimento di una primitiva o una lacuna di funzionalità solleva un’eccezione tipizzata e non passa mai silenziosamente a un algoritmo più debole. Per un livello che richiede la marca temporale (B-T, B-LT, B-LTA), una Time-Stamping Authority che restituisce un token vuoto è un errore terminale: la firma viene rifiutata, non emessa in uno stato privo di marca temporale e silenziosamente declassato, a meno che un gestore di guasti non sia configurato per autorizzare una degradazione documentata. L’attendibilità è controllata dal chiamante per progettazione — gli anchor e i criteri di revoca sono input, non valori predefiniti del motore — perché un produttore che asserisse l’attendibilità dichiarerebbe un fatto che solo il verificatore può stabilire. L’attendibilità della marca temporale si riduce all’attendibilità della Time-Stamping Authority, che è iniettabile affinché una distribuzione vincoli la propria. Questa pagina è contrassegnata come export_control_class: legal-review-required perché riguarda la firma crittografica; ogni fonte normativa è parafrasata e nessuna è riprodotta, in conformità all’igiene delle citazioni.

AffermazioneStandardClausolaEvidenza
La firma CMS è memorizzata in codifica DER nella voce Contents del dizionario della firma.ISO 32000-2§12.8.1
SignerInfo trasporta gli attributi firmati content-type e message-digest.RFC 5652§5.3
Il verificatore ricalcola il digest del contenuto e lo confronta con l’attributo message-digest.RFC 5652§5.4
Un token di marca temporale è prodotto da una TSA RFC 3161 e trasporta un serialNumber univoco e un genTime UTC.RFC 3161§2.4.1, §2.4.2,,
La convalida del percorso di certificazione verifica i vincoli di base e gli input del percorso dal firmatario fino a un anchor di attendibilità.RFC 5280§6.1,
OCSP segnala certStatus come good, revoked o unknown, delimitato da thisUpdate / nextUpdate.RFC 6960§2.2, §4.2,

Tutte le clausole sono parafrasate. NextPDF non riproduce il testo normativo. Consultare gli standard pubblicati per la formulazione autorevole.

Core fornisce il signer software CMS (RSA, RSASSA-PSS, ECDSA, Ed25519), l’uso di marche temporali RFC 3161, la convalida del percorso RFC 5280 e il controllo della revoca OCSP / CRL. La custodia delle chiavi HSM e PKCS#11, la firma differita e nel cloud, il produttore PAdES B-LT e B-LTA e il profilo dei criteri crittografici FIPS 140-3 sono forniti nelle edizioni Pro ed Enterprise. Core li risolve in fase di esecuzione tramite il contratto, perciò il motore open source non introduce alcuna dipendenza commerciale e l’API non cambia in caso di aggiornamento.