Pular para o conteúdo
getnextpdf.com

Enterprise edição

Segurança — Referência Profunda (HSM, PKCS#11, modo FIPS)

Esta página é a referência profunda combinada para a superfície de segurança do NextPDF Enterprise. Ela cobre a assinatura com token de hardware por PKCS#11, a assinatura por subprocesso através da interface de linha de comando (CLI) do OpenSSL, os presets de política criptográfica FIPS, o guard FIPS em tempo de execução e o guard de autoteste de inicialização. Existem dois complementos focados: HSM — Referência Profunda para o detalhe de signatário e FIPS 140 — Referência Profunda para o detalhe do módulo FIPS. O caminho de assinatura pós-quântica é uma prévia sem declaração de conformidade. O NextPDF não detém nenhuma certificação e não concede nenhuma; suporte não é igual a conformidade, e conformidade não é igual a certificação.

Esta capacidade é distribuída no NextPDF Enterprise (nextpdf/enterprise) e é ativada com um envelope de licença de nível Enterprise. Uma implantação sem esse direito não carrega as classes da capacidade. Compare edições e obtenha uma licença.

Terminal window
composer require nextpdf/enterprise:^3

Os tipos de assinatura ficam em NextPDF\Enterprise\Security\Signature\Hsm; os tipos FIPS ficam em NextPDF\Enterprise\Security\Fips; a raiz de composição fica em NextPDF\Enterprise\Bootstrap. Ambos os signatários implementam o contrato NextPDF\Contracts\HsmSignerInterface do Core. A política implementa os contratos NextPDF\Contracts\CryptoPolicyInterface e NextPDF\Contracts\PreOperationalSelfTestInterface do Core.

SímboloParâmetrosComportamento padrãoRetornaLança ou falha comObservações
Pkcs11Signer::__construct()string $libraryPath, int $slotId, string $pin, string $certLabel, ?string $keyLabel = null, array $chainDer = [], bool $enablePostQuantum = false, ?FipsSignatureEnforcer $fipsEnforcer = nullAbre a biblioteca do fornecedor, faz login no slot, carrega os metadados de certificado e de algoritmo de chaveHsmOperationException quando ext-pkcs11 está ausente ou o acesso ao token falhaPIN e rótulos são #[SensitiveParameter]; um handle de módulo é armazenado em cache por caminho de biblioteca por processo
Pkcs11Signer::isAvailable()NenhumInforma se ext-pkcs11 está carregadoboolNenhumEstático; verifique antes da construção
Pkcs11Signer::sign()string $data, string $algorithm = 'sha256WithRSAEncryption'Assina no token; a saída ECDSA bruta é convertida para DER ECDSA-Sig-Valuestring bytes brutos de assinaturaHsmOperationException (chave não encontrada, falha de token); InvalidArgumentException (algoritmo não mapeado); FipsViolationException / FipsModuleErrorStateException antes de assinar quando um enforcer está conectadoConjunto fechado de algoritmos; consulte o Contrato de comportamento
Pkcs11Signer::signPqs()string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = trueRecusado a menos que $enablePostQuantum tenha sido definido; despacha o mecanismo pós-quântico provisório do PKCS#11string bytes brutos de assinaturaHsmOperationException (desativado, falha de token, incompatibilidade de comprimento de assinatura); InvalidArgumentException (contexto acima de 255 bytes)Prévia; nenhuma declaração de conformidade
Superfície de acessores de Pkcs11SignerNenhumResultados de construção somente leiturabool / string / array<string>NenhumisPostQuantumEnabled, getCertificateDer, getCertificateChainDer, getPublicKeyAlgorithm
OpenSslCliSigner::__construct()string $keyUri, string $certPath, string $pin, array $extraCertPaths = [], OpenSslCliBackend $backend = OpenSslCliBackend::Auto, string $opensslBinary = 'openssl', int $timeoutSeconds = 30, ?string $modulePath = null, ?string $configPath = null, bool $legacyPinDelivery = false, ?FipsSignatureEnforcer $fipsEnforcer = nullVerifica proc_open, sonda o binário, resolve o backend, carrega os certificadosHsmOperationException (proc_open desativado, arquivo de módulo/config/certificado ausente, sem backend); InvalidArgumentException (pin-value dentro de $keyUri)Auto prefere o provider do OpenSSL 3.x, depois o engine
OpenSslCliSigner::sign()string $data, string $algorithm = 'sha256WithRSAEncryption'Assina em um subprocesso openssl; por padrão o PIN trafega por um arquivo pin-source efêmero 0600string bytes brutos de assinaturaHsmOperationException (timeout, PIN rejeitado, chave não encontrada, saída vazia); InvalidArgumentException (algoritmo não mapeado); exceções do gate FIPS antes de assinarO subprocesso é encerrado após $timeoutSeconds; o stderr é redigido
Superfície de acessores de OpenSslCliSignerNenhumResultados de construção somente leiturastring / array<string> / OpenSslCliBackendNenhumgetCertificateDer, getCertificateChainDer, getPublicKeyAlgorithm, getCertificatePem, getResolvedBackend, getOpensslVersion
OpenSslCliBackendEnum: Provider, Engine, AutoNenhumSeleção de backend para o signatário CLI
Pkcs11PqsAlgorithmEnum de conjuntos de parâmetros ML-DSA e SLH-DSANenhumAuxiliares: isMlDsa, isSlhDsa, mechanismId, parameterSetId, signatureLength, nistCategory
PqsCapabilityStatus::current()NenhumConstrói a postura pós-quântica honesta para o processoPqsCapabilityStatusNenhumTodo booleano de declaração de conformidade é fixado em false; nenhum sinalizador pode ativar um deles
HsmSignerProviderAdapterHsmSignerInterface $hsm, string $providerId, SignatureAlgorithm $algorithm = SignatureAlgorithm::Pkcs1v15Expõe uma implementação concreta de HSM como um SignerProviderInterface unificadoConforme o SPIKeyManagementException (versão de chave não nula); SignatureFailedException (falha de driver, assinatura vazia)Ids de provider: pkcs11-{module-id}, openssl-cli
HsmOperationExceptionFalha tipada para todo caminho de assinatura HSMEstende o NextPdfException do Core
FipsCryptoPolicy::strict() / ::standard()?FipsSelfTest $selfTest = nullPresets de fábrica; strict é o perfil FIPS 140-3, standard acrescenta AES-128-CBCFipsCryptoPolicyNenhumAllow-lists imutáveis; consulte o Comportamento em modo FIPS
Superfície de predicados de FipsCryptoPolicyentradas string / intVerificações de pertencimento à allow-listbool / stringNenhumisHashAlgorithmAllowed, isSignatureAlgorithmAllowed, isEncryptionAlgorithmAllowed, isKeyStrengthAllowed, getPreferredHashAlgorithm, getName
FipsCryptoPolicy::assertPreOperational()NenhumExecuta (ou reexecuta) o autoteste de inicializaçãovoidFipsModuleErrorStateExceptionAcionado pela junção de enforcement do Core na primeira operação criptográfica
FipsModeGuard::__construct()CryptoPolicyInterface $policy, ?FipsBootGuard $bootGuard = null, ?FipsAuditLogger $auditLogger = nullEnvolve uma política com limites no estilo assertNenhumSem um boot guard, o gate de autoteste está ausente (somente política)
Superfície de assert de FipsModeGuardentradas string / intCatálogo de negação primeiro, depois allow-list; registro de auditoria antes de qualquer throwvoidFipsViolationException; FipsModuleErrorStateException (boot guard conectado)assertHashAllowed, assertSignatureAlgorithmAllowed, assertEncryptionAllowed, assertKeyStrengthAllowed, além de getPolicy
FipsBootGuard::report() / ::rerun()NenhumExecuta a bateria de autoteste (em cache / forçada)FipsSelfTestReportNenhumUm relatório de ERROR trava o processo; uma reexecução bem-sucedida nunca libera a trava
FipsBootGuard::assertOperational()NenhumAssere que o módulo está OPERATIONALvoidFipsModuleErrorStateExceptionPersistente: um ERROR travado no processo rejeita até mesmo uma instância limpa
FipsBootGuard::status()NenhumInforma o status em cacheFipsSelfTestStatusNenhumPRE_OPERATIONAL, OPERATIONAL ou ERROR
FipsSelfTest::run()NenhumExecuta a bateria completa de known-answer test; nunca faz curto-circuitoFipsSelfTestReportNenhumO construtor aceita providers de hash e de random-bytes injetáveis para testes determinísticos
FipsSelfTestReport / FipsSelfTestResult / FipsSelfTestStatusValue objects de relatório e enum de statusFipsSelfTestReport::assertOperational() lança FipsModuleErrorStateExceptionresults sempre lista todos os resultados como evidência de auditoria
FipsSignatureEnforcer::assertSignatureGenerationAllowed()string $algorithm, string $certificatePemResolve o OID de assinatura e a força de chave, depois delega ao guardvoidFipsViolationException (não permitido ou não classificável, fail-closed)O ponto de estrangulamento que ambos os signatários chamam no início de sign() no modo FIPS
FipsAuditLoggerCryptoPolicyInterface $policy, LoggerInterface $loggerEmite registros ALLOW (INFO) / DENY (WARNING) por decisãobool por chamada de logNenhumlogHashOperation, logSignatureOperation, logEncryptionOperation, logKeyStrengthCheck
FipsTransitioningAlgorithmsentradas string / intCatálogo de negação estático NIST SP 800-131Abool / arrayNenhumA camada de negação explícita sob cada limite de guard
FipsBootstrap::boot() / ::lazy()?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null, ?LoggerInterface $auditLogger = nullCompõe boot guard, política e mode guard; boot() executa o autoteste imediatamente, lazy() o adia até o primeiro limiteFipsModeGuardboot(): FipsModuleErrorStateException em um teste com falhaAssume a política strict por padrão
FipsBootstrap::signatureEnforcer()?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = nullInicializa o módulo e retorna o gate em tempo de geração para os signatáriosFipsSignatureEnforcerFipsModuleErrorStateExceptionPasse o resultado ao parâmetro $fipsEnforcer de um signatário
FipsBootstrap::selfTestReport()?FipsSelfTest $selfTest = nullExecuta a bateria sob demanda e a resumearray{status, operational, failed}NenhumDestinado a endpoints de health e ao subcomando de CLI
FipsViolationException / FipsModuleErrorStateExceptionFalhas FIPS tipadasExpõem policyName / violatingItem / reason e failedResults, respectivamente
public function __construct(private readonly string $libraryPath, private readonly int $slotId, #[SensitiveParameter] private readonly string $pin, #[SensitiveParameter] private readonly string $certLabel, #[SensitiveParameter] private readonly ?string $keyLabel = null, array $chainDer = [], private readonly bool $enablePostQuantum = false, ?FipsSignatureEnforcer $fipsEnforcer = null)
public static function isAvailable(): bool
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): string
public function signPqs(string $data, Pkcs11PqsAlgorithm $algorithm, string $context = '', bool $randomized = true): string
public function __construct(private string $keyUri, string $certPath, #[SensitiveParameter] private string $pin, array $extraCertPaths = [], private OpenSslCliBackend $backend = OpenSslCliBackend::Auto, private string $opensslBinary = 'openssl', private int $timeoutSeconds = 30, private ?string $modulePath = null, private ?string $configPath = null, private bool $legacyPinDelivery = false, private ?FipsSignatureEnforcer $fipsEnforcer = null)
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): string
public static function strict(?FipsSelfTest $selfTest = null): self
public static function standard(?FipsSelfTest $selfTest = null): self
public function assertPreOperational(): void
public function __construct(private CryptoPolicyInterface $policy, private ?FipsBootGuard $bootGuard = null, private ?FipsAuditLogger $auditLogger = null)
public function assertHashAllowed(string $algorithm): void
public function assertSignatureAlgorithmAllowed(string $oid): void
public function assertEncryptionAllowed(string $algorithm): void
public function assertKeyStrengthAllowed(string $keyType, int $bitLength): void
public function getPolicy(): CryptoPolicyInterface
public static function boot(?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null, ?LoggerInterface $auditLogger = null): FipsModeGuard
public static function lazy(?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null, ?LoggerInterface $auditLogger = null): FipsModeGuard
public static function signatureEnforcer(?CryptoPolicyInterface $policy = null, ?FipsSelfTest $selfTest = null): FipsSignatureEnforcer
public static function selfTestReport(?FipsSelfTest $selfTest = null): array
  • Resolução de contrato. Ambos os signatários implementam o HsmSignerInterface do Core; a política implementa o CryptoPolicyInterface do Core. O código chamador depende dos contratos, então um upgrade de edição muda a composição, não os pontos de chamada.
  • Custódia de chave. A chave privada nunca deixa o limite do token. O Pkcs11Signer delega a operação ao token; o OpenSslCliSigner passa uma referência de chave por URI PKCS#11 ao subprocesso. O NextPDF não armazena, gera nem garante a segurança da chave de assinatura. A proteção da chave é responsabilidade de custódia do operador (NIST SP 800-57 Part 1 Rev.5 §5.5.2).
  • Sessão e login. A operação de assinatura do token, a sessão e o login do usuário seguem PKCS#11 v3.1 §5. O rótulo do certificado e o rótulo da chave privada podem diferir; o construtor aceita um rótulo de chave separado para esses tokens.
  • Conjunto fechado de algoritmos. Os signatários aceitam exatamente: RSA PKCS#1 v1.5 com SHA-256/384/512, RSASSA-PSS com SHA-256/384/512 e ECDSA com SHA-256/384/512 (o Pkcs11Signer também aceita ecdsa-raw). Qualquer outro identificador lança InvalidArgumentException; nenhum algoritmo substituto é jamais assinado.
  • Vinculação de salt PSS. Para toda variante PSS, o comprimento do salt é igual ao comprimento do resumo — 32, 48 ou 64 bytes — e os parâmetros de hash e de geração de máscara correspondem ao resumo escolhido (PKCS#11 v3.1 §5).
  • Conversão ECDSA. Os mecanismos de token ECDSA retornam uma assinatura bruta; sign() a converte para a forma ECDSA-Sig-Value codificada em DER para interoperabilidade com PDF e OpenSSL. A geração de assinatura segue FIPS 186-5 §6.3.2.
  • Conteúdo dos presets. O preset strict permite SHA-256/384/512; OIDs de assinatura RSA e ECDSA com esses hashes; RSASSA-PSS; AES-256-CBC e AES-256-GCM; mínimo de RSA 2048 e EC 256. O preset standard permite adicionalmente AES-128-CBC para interoperabilidade legada. Qualquer uso de AES-GCM exige um vetor de inicialização único por chave (NIST SP 800-38D §5).
  • Enforcement em duas camadas. Cada limite de guard consulta primeiro o catálogo de negação explícito NIST SP 800-131A, depois a allow-list da política. A camada de negação produz o sinal “não permitido” claro para auditoria; a allow-list permanece autoritativa.
  • Autoteste de inicialização. A bateria cobre SHA-256/384/512, HMAC-SHA-256, AES-256-CBC, AES-256-GCM, um teste de consistência de par (pairwise) ECDSA P-256 e uma verificação de saúde de bits aleatórios. A primeira operação criptográfica sob a política no caminho do Core a executa uma vez por processo, fail-closed. Uma falha coloca o módulo no estado ERROR; os serviços criptográficos são recusados até a redefinição. Isso segue ISO/IEC 19790:2025 §7.10, §7.10.2, §7.10.3 e §7.10.3.p3.
  • Estado ERROR persistente. Um ERROR observado trava para todo o processo. Construir uma nova política ou boot guard não o limpa; uma reexecução bem-sucedida não o elimina. Apenas uma reinicialização do processo — um verdadeiro ciclo de energia — redefine o estado.
  • Apenas gate de geração. O FipsSignatureEnforcer governa a produção de novas assinaturas. A validação de assinaturas pré-existentes é uso legado e nunca passa pelo enforcer.
  • Trilha de auditoria. Quando um guard é composto com um audit logger, cada limite emite um registro ALLOW ou DENY antes de permitir ou rejeitar a operação. O logger consulta a mesma política que o guard aplica, então a decisão registrada não pode divergir.
  • Construir o Pkcs11Signer sem ext-pkcs11 lança HsmOperationException imediatamente; a extensão não acompanha as distribuições padrão do PHP.
  • Um rótulo de certificado ou de chave privada que não corresponde a nenhum objeto do token lança HsmOperationException nomeando a classe de objeto ausente.
  • O OpenSslCliSigner recusa um $keyUri que contenha pin-value na construção, fail-closed; em vez disso, o PIN trafega pelo caminho seguro de pin-source.
  • No modo FIPS, um identificador de algoritmo que não pode ser mapeado para um OID de assinatura conhecido é negado fail-closed; o mesmo vale para um certificado cuja força de chave pública não pode ser determinada.
  • Um tipo de chave desconhecido é negado por padrão; a política nunca recorre a um algoritmo mais fraco.
  • Um known-answer test com falha lança FipsModuleErrorStateException carregando os resultados que falharam; todo limite posterior no processo repete a falha até a reinicialização.
  • Um guard construído sem um boot guard aplica as allow-lists, mas não fornece gate de autoteste; a composição FIPS de produção fornece um por meio do bootstrap.
  • signPqs() recusa-se a executar a menos que o opt-in do construtor tenha sido definido. Uma string de contexto acima de 255 bytes lança InvalidArgumentException (FIPS 204 §5.4). Uma assinatura retornada cujo comprimento em bytes não corresponde ao conjunto de parâmetros selecionado é rejeitada antes de chegar à codificação.

Permitido por FIPS no modo strict: SHA-256/384/512; RSA PKCS#1 v1.5 e RSA-PSS com esses hashes; ECDSA com esses hashes; AES-256-CBC e AES-256-GCM; RSA de pelo menos 2048 bits, EC de pelo menos 256 bits. Rejeitado por FIPS no modo strict: hashes mais fracos ou legados, OIDs de assinatura não aprovados, AES-128 (permitido apenas no preset standard) e qualquer chave abaixo da força mínima. O comprimento mínimo de chave RSA e o status de transição seguem NIST SP 800-131A Rev.2 §3. O par de curva e hash ECDSA segue FIPS 186-5 §6.1.1. O caminho é fail-closed e nunca substitui por um algoritmo mais fraco.

O NextPDF Enterprise não é um módulo criptográfico validado por FIPS e não faz nenhuma declaração de certificação FIPS. O NextPDF Enterprise opera em um modo compatível com FIPS apenas quando é configurado com um provedor de criptografia validado por FIPS — por exemplo, um provider OpenSSL validado por FIPS — ou um HSM validado por FIPS. A política de modo FIPS auxilia a conformidade; ela não é uma certificação. Nenhum artefato de certificação FIPS existe neste repositório.

DeclaraçãoPadrãoCláusula
Semântica da operação de assinatura, sessão e login do usuário do tokenPKCS#11 v3.1§5 (sign)
O comprimento do salt PSS é igual ao comprimento do resumoPKCS#11 v3.1§5 (PSS sLen)
Geração de assinatura ECDSA; par de curva e hashFIPS 186-5§6.3.2; §6.1.1
Comprimento mínimo de chave RSA e status de transição de geração de assinaturaNIST SP 800-131A Rev.2§3
Categoria de autoteste, documentação, gatilho condicional, conjunto disjuntoISO/IEC 19790:2025§7.10, §7.10.2, §7.10.3, §7.10.3.p3
Unicidade do vetor de inicialização AES-GCMNIST SP 800-38D§5
Responsabilidades de proteção e custódia de chaveNIST SP 800-57 Part 1 Rev.5§5.5.2
String de contexto de assinatura pós-quântica limitada a 255 bytesFIPS 204§5.4

Todas as cláusulas são parafraseadas; nenhum texto normativo é reproduzido. Estas são declarações de capacidade sobre o código do NextPDF, não certificações. Se uma assinatura produzida é verificada com sucesso é decisão do verificador contra sua própria configuração de confiança. A política de modo FIPS é um recurso de assistência à conformidade, não um parecer jurídico; consulte seus próprios assessores de conformidade e jurídicos. Este módulo diz respeito a funcionalidade criptográfica; trate-o como sensível à segurança em sua própria revisão.

  • Componha o modo FIPS por meio do bootstrap: boot() para um gate de inicialização, lazy() para adiar a bateria até o primeiro limite e a fábrica de enforcer para o parâmetro $fipsEnforcer dos signatários. Implantações não FIPS passam null e o comportamento permanece inalterado.
  • O subcomando fips:self-test de bin/nextpdf-enterprise executa a bateria sob demanda e sai com código diferente de zero no estado ERROR; conecte-o a jobs de manutenção ou a endpoints de health apenas de administrador (autotestes sob demanda da ISO/IEC 19790:2025).
  • FipsBootGuard::resetProcessErrorLatchForTesting() é @internal e apenas para testes; o código de produção nunca o chama, porque isso anularia o estado ERROR persistente.
  • Construa os signatários uma vez e reutilize-os; a construção faz login e lê o certificado, e o cache de módulo por biblioteca torna segura a construção repetida contra a mesma biblioteca.
  • Forneça o PIN a partir de um gerenciador de segredos. Ele é um #[SensitiveParameter], nunca registrado em log ou serializado; não o faça commit na configuração.
  • O operador é dono do provisionamento de token, do tratamento de PIN, da configuração de slot, da proteção de rede de um HSM conectado à rede e da configuração de confiança. Esta página não expõe os detalhes internos de política de PIN de token nem material de credencial de fornecedor.
  • Não ative a prévia pós-quântica para assinaturas AdES de produção. O catálogo de suítes criptográficas AdES ainda não reconhece suítes pós-quânticas, a maioria dos visualizadores de PDF rejeita tais assinaturas e a validação de ida e volta em hardware não está completa. O detalhe interno de mecanismo permanece na documentação interna do repositório de origem e está fora do escopo deste manual.

Esta página documenta apenas o comportamento observável externamente e a superfície de API pública suportada. Caminhos de namespace internos, classes auxiliares, tabelas de mecanismo, nomes de arquivo de runbook e prefixos de tíquete estão fora do escopo.