Segurança: criptografia, política de criptografia e superfície de assinatura
Visão geral
Seção intitulada “Visão geral”O módulo de segurança do Core aplica criptografia a documentos com Advanced Encryption Standard de 256 bits (AES-256), encaminha cada escolha de algoritmo por um contrato de política de criptografia e expõe pontos de integração para um serviço de gerenciamento de chaves gerenciado pela implantação. A proteção efetiva do documento depende do manuseio das chaves, da força da senha, do leitor que consome o documento e do ambiente de implantação. Esta página declara esses limites com clareza.
Instalação
Seção intitulada “Instalação”composer require nextpdf/core:^3Visão conceitual
Seção intitulada “Visão conceitual”O módulo de segurança tem três superfícies. A superfície de criptografia usa o ponto de entrada de documento setEncryption() para configurar o handler de segurança Standard AES-256. O controle de política de criptografia usa CryptoPolicyInterface para decidir quais hashes, assinaturas, cifras e forças de chave uma implantação permite. A superfície de assinatura é mencionada aqui, mas documentada separadamente; consulte Assinatura.
A criptografia usa AES-256 conforme definido em ISO 32000-2:2020 §7.6. O caminho padrão é o handler de segurança Standard V=5 / R=6 com o crypt filter AESV3. A chave do arquivo tem 32 bytes (256 bits), o que corresponde ao Federal Information Processing Standards (FIPS) 197. Um caminho opcional adiciona criptografia autenticada ISO/TS 32003:2023 V=6 / R=7 AES-256 em Galois/Counter Mode (AES-256-GCM). A página detalhada documenta os dois caminhos: Criptografia.
O controle de política de criptografia é um predicado de negar ou permitir. O Core consulta CryptoPolicyInterface antes de qualquer etapa de assinatura, criptografia ou hashing. Se nenhuma política for definida, o Core permite todos os algoritmos. Esse padrão aberto é adequado para desenvolvimento, mas não para produção. Uma implantação regulada deve definir uma política explícita. Contracts / Security Policy documenta a superfície do contrato.
As flags de permissão são a fonte mais comum de afirmações exageradas, por isso esta página as trata de forma explícita. A bitmask de permissão é armazenada na entrada criptografada /Perms e no valor /P. Espera-se que um leitor em conformidade respeite essas restrições. As flags não são impostas pela criptografia. Um processador que ignora os bits ainda pode ler, copiar ou modificar o conteúdo depois de obter a chave de descriptografia. Declare esse limite a qualquer parte que dependa das flags de permissão.
O gerenciamento de chaves e a integração com Public-Key Cryptography Standards #11 (PKCS#11) são pontos de contrato. O Core inclui um caminho de chave local. O value object KeyMaterial encapsula uma chave de 256 bits com comprimento verificado e evita divulgação nas saídas de string e de depuração. O caminho de custódia de chave via hardware security module (HSM)/PKCS#11 é um recurso Enterprise controlado pelos mesmos contratos; esta página nomeia o ponto de integração, mas não documenta a implementação Enterprise.
Superfície de API
Seção intitulada “Superfície de API”| Tipo | Categoria | Membros principais | Estabilidade | Desde |
|---|---|---|---|---|
Document::setEncryption() | método (concern HasSecurity) | userPassword, ownerPassword, permissions | estável | 1.0.0 |
Document::useAesGcm() | método (concern HasSecurity) | ?bool $enabled — opcional ISO/TS 32003 V=6/R=7 | estável | 2.18.0 |
Aes256Encryptor | classe | encrypt(), decrypt(), buildEncryptionDictionary(), verifyUserPassword(), verifyOwnerPassword(), validatePerms() | estável | 1.0.0 |
Aes256GcmEncryptor | classe | encrypt(), decrypt(), encryptStream(), assertWithinSafetyBound(), invocationCount() | estável | 2.18.0 |
KeyMaterial | final readonly class | generate(), exposeKey(), fingerprint() | estável | 2.18.0 |
CryptoPolicyInterface | interface | isHashAlgorithmAllowed(), isSignatureAlgorithmAllowed(), isEncryptionAlgorithmAllowed(), isKeyStrengthAllowed(), getPreferredHashAlgorithm(), getName() | estável | 1.9.0 |
Config::withCryptoPolicy() | método | CryptoPolicyInterface $policy | estável | 1.9.0 |
CryptoCapabilities | final class | hasAesGcm(), detectFipsMode(), assertFipsAvailableForProfile() | estável | 2.0.0 |
Exemplo de código — Início rápido
Seção intitulada “Exemplo de código — Início rápido”<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Encrypted Document — Restricted Permissions');
// Call setEncryption() BEFORE addPage().// Permission bit 3 (value 4) = printing allowed; all other operations denied.$doc->setEncryption( userPassword: 'demo', ownerPassword: 'admin', permissions: 4,);
$doc->addPage();$doc->setFont('helvetica', 'B', 20);$doc->cell(0, 14, 'Encrypted PDF Document', newLine: true);
$doc->save(__DIR__ . '/output/22-protection.pdf');A senha de usuário abre o documento. A senha de proprietário concede acesso total. As flags de permissão restringem apenas leitores em conformidade.
Exemplo de código — Produção
Seção intitulada “Exemplo de código — Produção”<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\CryptoPolicyInterface;use NextPDF\Core\Document;use Psr\Log\LoggerInterface;
final readonly class PolicyGatedEncryption{ public function __construct( private CryptoPolicyInterface $cryptoPolicy, private LoggerInterface $logger, ) {}
/** * Encrypt only when the active policy permits AES-256-CBC. * * @param non-empty-string $userPassword Opens the document. * @param non-empty-string $ownerPassword Grants full access. */ public function protect( Document $doc, string $userPassword, string $ownerPassword, int $permissions, ): void { if (!$this->cryptoPolicy->isEncryptionAlgorithmAllowed('aes-256-cbc')) { $this->logger->error('Encryption refused by crypto policy', [ 'policy' => $this->cryptoPolicy->getName(), ]);
throw new \RuntimeException('AES-256-CBC denied by the active crypto policy.'); }
$doc->setEncryption($userPassword, $ownerPassword, $permissions);
$this->logger->info('Document encrypted', [ 'policy' => $this->cryptoPolicy->getName(), 'algorithm' => 'aes-256-cbc', ]); }}Esse controle consulta a política antes da criptografia, registra o nome da política na trilha de auditoria e lança uma exceção específica quando a política nega a cifra.
Casos extremos e armadilhas
Seção intitulada “Casos extremos e armadilhas”- Chame
setEncryption()antes deaddPage(). Uma chamada posterior não criptografa retroativamente o conteúdo que o writer já emitiu. - O modo PDF/A e a criptografia são mutuamente exclusivos. ISO 19005 proíbe a chave de trailer
Encryptem qualquer variante de PDF/A, portantosetEncryption()euseAesGcm()lançam uma exceção quando um gerenciador de PDF/A está ativo. - Dentro de
setEncryption(), uma senha de proprietário vazia passa a usar a senha de usuário. Um documento com uma única senha compartilhada concede ao detentor da senha de usuário acesso de nível de proprietário. - Quando nenhuma política é injetada,
CryptoPolicyInterfacepermite todos os algoritmos. Trate o padrão aberto como uma conveniência de desenvolvimento e defina uma política explícita em qualquer implantação regulada. - As flags de permissão são consultivas para o leitor. Não as descreva como controle de acesso que um processador hostil não possa contornar.
Desempenho
Seção intitulada “Desempenho”setEncryption() executa uma rotina iterada de derivação de chave (Algorithm 2.B, revision 6) durante a construção do documento. O custo é limitado e constante por documento; ele não escala com a contagem de páginas. A criptografia por objeto realiza uma operação AES por stream ou string. O caminho opcional AES-256-GCM adiciona 28 bytes de sobrecarga por objeto (initialization vector (IV) de 12 bytes mais tag de 16 bytes) e transmite conteúdo grande em blocos de 16 MiB. Isso mantém a operação de streaming abaixo do pico documentado de 64 MB. O performance_budget de 1500 ms de wall e 64 MB de pico é dominado pela renderização do documento, não pela criptografia.
Notas de segurança
Seção intitulada “Notas de segurança”O modelo de ameaças é explícito. O controle de política de criptografia mitiga o downgrade de algoritmo ao recusar cifras fracas, hashes fracos e chaves curtas antes de qualquer operação. O motor não substitui silenciosamente por um primitivo mais fraco quando o solicitado está ausente; ele lança uma exceção para que o operador possa agir. KeyMaterial mitiga a divulgação de chave por meio de logging: suas formas de string e de depuração ocultam os bytes e expõem apenas um fingerprint não reversível. A adulteração de texto cifrado é detectada apenas no caminho opcional AES-256-GCM, onde a tag de autenticação é verificada e uma incompatibilidade lança uma exceção em vez de retornar texto em claro. O caminho padrão AES-256 Cipher Block Chaining (AES-256-CBC) oferece somente confidencialidade e não detecta modificação por si só. No caminho GCM, a reutilização de IV é mitigada por um contador monotônico mais um conjunto de controle de colisões como defesa em profundidade, em conformidade com o requisito de IV único em NIST SP 800-38D §8.
O limite é igualmente explícito. A criptografia AES-256 é aplicada conforme definido em ISO 32000-2:2020 §7.6. A proteção efetiva depende da força da senha, do gerenciamento de chaves, do ambiente de implantação e do leitor que consome o documento. Leitores em conformidade respeitam as flags de permissão, mas a criptografia não as impõe. A sondagem de modo FIPS informa se a build do OpenSSL do host carregou um provedor FIPS. A biblioteca opera em um modo compatível com FIPS quando o host fornece um módulo validado; ela não certifica nenhum módulo. NIST SP 800-57 Part 1 §4 enquadra o tempo de vida da chave e o cryptoperiod como responsabilidades da implantação. O Core expõe os controles, e a implantação define a política de rotação.
Residência de dados e mitigações de PII
Seção intitulada “Residência de dados e mitigações de PII”A superfície de criptografia não transmite os bytes do documento, incluindo qualquer informação de identificação pessoal (PII) contida neles, para fora do host. A derivação de chave, a criptografia e a descriptografia são executadas em processo. O caminho opcional GCM mantém em memória um índice do conjunto de colisões de IV por fingerprint de chave não reversível, não pelos bytes da chave. O módulo de segurança não grava nenhuma senha nem valor de chave em disco. Uma implantação que encaminha chaves por um serviço externo de gerenciamento de chaves é responsável pela residência desse serviço.
Telemetria segura e limpeza de logs
Seção intitulada “Telemetria segura e limpeza de logs”KeyMaterial::__toString() e __debugInfo() retornam um placeholder mascarado, de modo que um log acidental de um objeto de chave gera um fingerprint, não bytes de chave. As senhas passadas para setEncryption() carregam o atributo #[\SensitiveParameter], que as oculta de um stack trace. Para auditorias, use o nome da política de CryptoPolicyInterface::getName() e o fingerprint de chave de 8 caracteres como identificadores da operação de criptografia. Registre esses valores, nunca a chave nem a senha.
Modelo de ameaças
Seção intitulada “Modelo de ameaças”| Ameaça | Mitigação no Core | Limite residual |
|---|---|---|
| Downgrade de algoritmo / substituição por cifra fraca | Controle de política de criptografia; sem degradação silenciosa (lança UnsupportedAlgorithmException) | Efetivo apenas quando uma política é injetada |
| Divulgação de chave por logs | KeyMaterial faz o mascaramento; #[\SensitiveParameter] nas senhas | Um chamador que passa exposeKey() para um logger anula isso |
| Adulteração de texto cifrado | Verificação da tag GCM no caminho opcional | O caminho padrão CBC oferece somente confidencialidade |
| Reutilização de IV (GCM) | Contador monotônico mais conjunto de colisões; o estouro recusa | — |
| Bypass de flag de permissão | Nenhuma; as flags são consultivas | Um leitor não conforme ignora as flags |
| Força bruta sobre uma senha fraca | SASLprep mais derivação de chave iterada aumenta o custo | Uma senha fraca permanece o risco dominante |
Comportamento do modo FIPS
Seção intitulada “Comportamento do modo FIPS”O Core não é um módulo criptográfico validado por FIPS e não possui certificação FIPS. CryptoCapabilities::detectFipsMode() é uma sondagem em tempo de execução de melhor esforço: ela lê uma substituição do operador, depois a lista de provedores do OpenSSL, depois a chamada legada de modo FIPS, e reporta active, absent ou indeterminate. assertFipsAvailableForProfile() falha de modo fechado quando um perfil FIPS é selecionado em um host que não consegue comprovar um provedor FIPS. A biblioteca opera em um modo compatível com FIPS quando é configurada com uma build do OpenSSL do host que carregou um provedor validado por FIPS. Uma postura validada e certificada para FIPS é uma questão Enterprise; consulte a documentação Enterprise.
Conformidade
Seção intitulada “Conformidade”| Afirmação | Norma | Cláusula | Evidência |
|---|---|---|---|
| O caminho GCM mantém cada IV único para uma invocação, em conformidade com o requisito de unicidade da norma. | NIST SP 800-38D | §8.2.1 | |
| O Core expõe controles para o tempo de vida da chave e o cryptoperiod; a implantação é responsável pela política. | NIST SP 800-57 Part 1 Rev. 5 | §4 | |
| A chave de arquivo AES tem 256 bits, o que corresponde ao comprimento de chave da norma. | FIPS 197 | §4.2.1 | |
| A geração de chave residente no token é o ponto de integração para um armazenamento de chaves externo. | OASIS PKCS#11 v3.1 | C_GenerateKey |
ISO 32000-2:2020 §7.6 é a base normativa para o handler de segurança Standard. Seu texto é restrito por licença e é parafraseado aqui, nunca citado; esta página cita a cláusula pelo número. Cada ponto acima é parafraseado da norma citada.
Contexto comercial
Seção intitulada “Contexto comercial”O Core define e estabiliza o contrato de política de criptografia, inclui o caminho de criptografia AES-256 e fornece uma superfície de chave local. A edição Enterprise fornece um caminho de custódia de chave HSM/PKCS#11 e um perfil de política de criptografia em modo FIPS por trás da mesma CryptoPolicyInterface. A superfície do contrato é idêntica entre as edições; a implantação injeta uma implementação de política diferente e um backend de custódia de chave diferente.
Veja também
Seção intitulada “Veja também”- Security / Encryption — a referência detalhada sobre AES-256 e AES-256-GCM.
- Contracts / Security Policy — os contratos de política de criptografia e de política de recursos.
- Security / Signing — PDF Advanced Electronic Signatures (PAdES), Cryptographic Message Syntax (CMS) e timestamps.
- Audit — logging de auditoria de nome de política e de operação.
- Conformance — interação do PDF/A com a criptografia.