Pro edição
Assinatura com Cloud KMS — Referência Profunda
Visão geral
Seção intitulada “Visão geral”Esta página é a referência em nível de contrato para a superfície de assinatura com cloud KMS do NextPDF Pro. A superfície consiste em uma Service Provider Interface, NextPDF\Pro\Security\Signing\Kms\KmsSignerInterface, e três signers de provedor: AwsKmsSigner, AzureKeyVaultSigner e GcpKmsSigner. Dois adaptadores, AwsKmsSigningStrategy e AzureKeyVaultSigningStrategy, conectam um signer ao contrato SigningStrategy do Pro. Cada signer envia apenas um digest de mensagem ao seu provedor via HTTP PSR-18. A chave privada e o documento nunca cruzam a fronteira. Esta página declara a API pública, o contrato de comportamento observável e os modos de falha tipados. A orquestração de sessão (RemoteSigningSession, SequentialSigner) e o timestamping (PadesBtTimestamper) ficam em suas próprias páginas.
Disponibilidade e licenciamento
Seção intitulada “Disponibilidade e licenciamento”Esta capacidade é distribuída no NextPDF Pro (nextpdf/pro) e é ativada com um envelope de licença de nível Pro. Uma implantação sem essa habilitação não carrega as classes da capacidade. Compare as edições e obtenha uma licença.
Superfície da API pública
Seção intitulada “Superfície da API pública”| Símbolo | Parâmetros | Comportamento padrão | Retorna | Lança ou falha com | Notas |
|---|---|---|---|---|---|
KmsSignerInterface | — | Estende o contrato Core HsmSignerInterface | — | — | SPI para drivers KMS e HSM; ids embutidos reservados: aws-kms, azure-keyvault, gcp-kms, pkcs11, openssl-cli |
KmsSignerInterface::providerId() | nenhum | Chave estável de lookup no registro | non-empty-string | — | Drivers de terceiros devem usar namespace no seu identificador |
KmsSignerInterface::signWithVersion() | $data, $algorithm = 'sha256WithRSAEncryption', $keyVersion = null | Versão de chave null recorre ao padrão do provedor | octetos de assinatura string: RSA como retornado pelo provedor (colocado diretamente em SignerInfo.signature), ECDSA como DER ECDSA-Sig-Value conforme as regras do CMS | KeyManagementException, UnsupportedAlgorithmException, SignatureFailedException | A semântica de null difere por provedor; veja o contrato de comportamento |
KmsSignerInterface::supportsAlgorithm() | string $algorithm | Sonda de capacidade; não realiza I/O | bool | — | Chamado antes da seleção do provedor |
KmsSignerInterface::supportedAlgorithms() | nenhum | Lista os nomes no estilo OpenSSL que o provedor aceita | list<non-empty-string> | — | — |
AwsKmsSigner | construtor: AwsKmsConfig, cert DER, chain DER, cliente PSR-18, fábricas PSR-17, logger PSR-3 | O algoritmo assume por padrão KmsSigningAlgorithm::RsaPkcs1Sha256 | — | veja os métodos | final; PROVIDER_ID = 'aws-kms' |
AwsKmsSigner::create() | id da chave, cert DER, dependências PSR, chain opcional, config, logger | Constrói AwsKmsConfig::fromEnvironment($keyId) quando $config é null | self | — | Lê as variáveis de ambiente padrão AWS_* |
AwsKmsSigner::withAlgorithm() | KmsSigningAlgorithm $algorithm | Retorna um clone modificado | self | — | Deve corresponder ao tipo de chave provisionado no AWS KMS |
AwsKmsSigner::sign() | $data, $algorithm = 'sha256WithRSAEncryption' | Delega a signWithVersion($data, $algorithm, null) | string | como signWithVersion() | Caminho legado do contrato Core de dois argumentos |
AzureKeyVaultSigner | construtor: AzureKeyVaultConfig, cert DER, chain DER, cliente PSR-18, fábricas PSR-17, logger PSR-3 | O algoritmo assume por padrão AzureSigningAlgorithm::Rs256; um token de acesso da config semeia o bearer token | — | veja os métodos | final; PROVIDER_ID = 'azure-keyvault' |
AzureKeyVaultSigner::create() | nome do vault, nome da chave, cert DER, dependências PSR, chain opcional, config, logger | Constrói AzureKeyVaultConfig::fromEnvironment() quando $config é null | self | — | Suporta token pré-obtido ou credenciais de service principal |
AzureKeyVaultSigner::withAlgorithm() | AzureSigningAlgorithm $algorithm | Retorna um clone modificado | self | — | Chaves RSA usam valores RS/PS; chaves EC usam valores ES |
GcpKmsSigner | construtor: GcpKmsConfig, cert DER, chain DER, cliente PSR-18, fábricas PSR-17, logger PSR-3 | O algoritmo assume por padrão GcpKmsSigningAlgorithm::RsaSignPkcs1_2048Sha256 | — | veja os métodos | final; PROVIDER_ID = 'gcp-kms', API_VERSION = 'v1' |
GcpKmsSigner::create() | id do projeto, localização, key ring, crypto key, cert DER, dependências PSR, chain opcional, config, logger | Constrói GcpKmsConfig::fromEnvironment() quando $config é null | self | — | A aquisição do bearer token é delegada ao chamador |
GcpKmsSigner::withAlgorithm() | GcpKmsSigningAlgorithm $algorithm | Apenas prévia em tempo de config; o nome de fio por chamada prevalece no momento da assinatura | self | — | O tamanho da chave é fixado pela CryptoKeyVersion provisionada |
AwsKmsSigningStrategy | construtor: AwsKmsSigner $signer | Síncrono; isAsync() retorna false | — | Propaga as exceções do signer encapsulado | Adaptador para RemoteSigningSession::complete() |
AzureKeyVaultSigningStrategy | construtor: AzureKeyVaultSigner $signer | Síncrono; isAsync() retorna false | — | Propaga as exceções do signer encapsulado | Adaptador para RemoteSigningSession::complete() |
KmsSigningAlgorithm | enum, 9 casos (RSA PKCS#1, RSA-PSS, ECDSA; SHA-256/384/512) | — | Valores de fio SigningAlgorithm do AWS KMS | InvalidArgumentException de fromOpenSslName() | resolveForWireName() preserva o digest PSS configurado |
AzureSigningAlgorithm | enum, 9 casos (RS256…ES512) | — | Valores estilo JWA do Azure Key Vault | InvalidArgumentException de fromOpenSslName() | isEcdsa() marca valores cuja saída precisa de conversão DER |
GcpKmsSigningAlgorithm | enum, 10 casos (EC P-256/P-384, RSA PKCS#1, RSA-PSS) | — | Valores de algoritmo CryptoKeyVersion do GCP | UnsupportedAlgorithmException de fromOpenSslName() | A resolução do nome de fio escolhe o menor tamanho de chave correspondente |
Assinaturas dos pontos de entrada
Seção intitulada “Assinaturas dos pontos de entrada”public function providerId(): string;
public function signWithVersion( string $data, string $algorithm = 'sha256WithRSAEncryption', ?string $keyVersion = null,): string;
public function supportsAlgorithm(string $algorithm): bool;
public function supportedAlgorithms(): array;public static function create( string $keyId, string $certDer, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, array $chainDer = [], ?AwsKmsConfig $config = null, ?LoggerInterface $logger = null,): self
public function withAlgorithm(KmsSigningAlgorithm $algorithm): self
public function sign(string $data, string $algorithm = 'sha256WithRSAEncryption'): stringpublic static function create( string $vaultName, string $keyName, string $certDer, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, array $chainDer = [], ?AzureKeyVaultConfig $config = null, ?LoggerInterface $logger = null,): self
public function withAlgorithm(AzureSigningAlgorithm $algorithm): selfpublic static function create( string $projectId, string $location, string $keyRing, string $cryptoKey, string $certDer, ClientInterface $httpClient, RequestFactoryInterface $requestFactory, StreamFactoryInterface $streamFactory, array $chainDer = [], ?GcpKmsConfig $config = null, ?LoggerInterface $logger = null,): self
public function withAlgorithm(GcpKmsSigningAlgorithm $algorithm): selfpublic function __construct( private AwsKmsSigner $signer,) {}
public function sign(string $signedAttributesDer): stringpublic function __construct( private AzureKeyVaultSigner $signer,) {}
public function sign(string $signedAttributesDer): stringContrato de comportamento
Seção intitulada “Contrato de comportamento”Resolução do contrato
Seção intitulada “Resolução do contrato”KmsSignerInterface estende o contrato Core HsmSignerInterface. Ele adiciona providerId(), o signWithVersion() ciente da versão de chave, e as sondas de capacidade supportsAlgorithm() e supportedAlgorithms(). O sign() herdado de dois argumentos delega a signWithVersion() com versão de chave null nos três signers. getCertificateDer(), getCertificateChainDer() e getPublicKeyAlgorithm() são implementados a partir do material fornecido pelo construtor. As sondas de capacidade não realizam I/O. Cada signer também expõe os acessadores getSigningAlgorithm() e getConfig() para inspeção.
Transmissão apenas do digest
Seção intitulada “Transmissão apenas do digest”Cada signer faz o hash de $data localmente com o digest do algoritmo resolvido e transmite apenas esse digest. A AWS recebe um digest em base64 com MessageType: DIGEST. O Azure recebe um digest em base64url no corpo da requisição de assinatura. O GCP recebe um digest em base64 no campo de digest específico do algoritmo. Os bytes do documento nunca aparecem em uma requisição ao provedor. Todo o transporte usa um cliente HTTP PSR-18 padrão sobre o endpoint HTTPS do provedor; nenhum SDK de fornecedor de nuvem está envolvido.
Resolução da versão de chave
Seção intitulada “Resolução da versão de chave”signWithVersion() valida o argumento de versão de chave de forma fail-closed antes de qualquer requisição ser construída. Um valor que não passa na gramática do provedor levanta KeyManagementException e impede a injeção de segmento de URL ou de KeyId.
| Provedor | Versão de chave null | String vazia | Gramática de override |
|---|---|---|---|
AwsKmsSigner | Usa AwsKmsConfig::$keyId; um alias ou ARN resolve para a chave atual no lado do provedor | Rejeitado | UUID (com ou sem traços), alias/<name>, ou um ARN de chave/alias do KMS |
AzureKeyVaultSigner | Usa a versão de chave configurada; um valor de config vazio seleciona a versão habilitada mais recente no servidor | Rejeitado | Identificador hexadecimal de 32 caracteres |
GcpKmsSigner | Usa a versão fixada em GcpKmsConfig; sem nenhuma fixada, levanta KeyManagementException | Rejeitado | Id decimal de CryptoKeyVersion, apenas dígitos |
O GCP não tem uma primitiva de “versão ativa” no servidor. O endpoint de assinatura assimétrica opera apenas sobre um recurso cryptoKeyVersions/{n} específico, então uma versão deve sempre ser resolvível.
Resolução de algoritmo
Seção intitulada “Resolução de algoritmo”A camada de estratégia encaminha um nome de fio no estilo OpenSSL. AWS e Azure aceitam sete nomes de fio (PKCS#1 e ECDSA em SHA-256/384/512, mais RSASSA-PSS). O GCP aceita cinco (sha256WithRSAEncryption, sha512WithRSAEncryption, RSASSA-PSS, ecdsa-with-SHA256, ecdsa-with-SHA384). O nome de fio RSASSA-PSS não codifica um digest, então é ambíguo quanto ao digest. AwsKmsSigner o resolve através de KmsSigningAlgorithm::resolveForWireName(), que preserva o digest da variante PSS configurada. AzureKeyVaultSigner confia na variante PSS configurada para o nome ambíguo. Ele levanta UnsupportedAlgorithmException se um digest PSS resolvido divergir do configurado. GcpKmsSigner re-resolve o enum a partir do nome de fio em cada chamada; withAlgorithm() no GCP é uma prévia em tempo de config e não altera o comportamento no momento da assinatura. Um nome de fio não suportado levanta UnsupportedAlgorithmException antes de qualquer chamada de rede. Em AwsKmsSigner e GcpKmsSigner, uma chamada de assinatura atualiza o valor posteriormente reportado por getSigningAlgorithm() para o algoritmo resolvido por chamada. Em AzureKeyVaultSigner, a resolução é local à chamada e o valor configurado permanece autoritativo.
Normalização de assinatura
Seção intitulada “Normalização de assinatura”AWS e GCP retornam assinaturas na forma que o CMS consome: os octetos de assinatura RSA vão para SignerInfo.signature sem alteração, e o ECDSA chega codificado em DER. O Azure retorna ECDSA em formato bruto IEEE P1363 (r||s), que o signer converte para um DER ECDSA-Sig-Value antes de retornar.
Integração com CMS e adjacência
Seção intitulada “Integração com CMS e adjacência”Um adaptador SigningStrategy assina os atributos assinados codificados em DER fornecidos pela sessão. Com atributos assinados presentes, a entrada da assinatura do CMS é o digest da codificação DER completa do valor SignedAttrs — RFC 5652 §5.4. O getSignatureAlgorithmOid() e o getDigestAlgorithm() do adaptador alimentam os campos signatureAlgorithm e digestAlgorithm do SignerInfo — RFC 5652 §5.3. Os bytes retornados tornam-se o OCTET STRING da assinatura do SignerInfo — RFC 5652 §5.5. A montagem do CMS, o tratamento de ByteRange e o ciclo de vida da sessão pertencem a RemoteSigningSession; os fluxos multipartes pertencem a SequentialSigner. Um carimbo de tempo de assinatura PAdES B-T, cujo messageImprint faz o hash do valor de assinatura do SignerInfo — RFC 3161 Appendix A — é aplicado por PadesBtTimestamper, não por estes signers. Todos os três estão documentados na referência detalhada de segurança do Pro.
Casos de borda e modos de falha
Seção intitulada “Casos de borda e modos de falha”- Uma versão de chave em string vazia é rejeitada nos três provedores. Passe
nullpara herdar o padrão configurado. - Uma versão de chave malformada é rejeitada antes de qualquer requisição ser construída, com o valor ofensivo nomeado na exceção.
AwsKmsSignercom umAwsKmsConfig::$keyIdvazio e uma versão de chavenulllevantaKeyManagementException.- Respostas do provedor que indicam uma falha de gerenciamento de chave mapeiam para
KeyManagementException: AWSNotFoundException,DisabledException,KeyUnavailableException,InvalidKeyUsageException, ou HTTP 404; Azure HTTP 404,KeyNotFound,KeyDisabled, ouKeyNotActive; GCP HTTP 404 ou 409,NOT_FOUND,FAILED_PRECONDITION, ou um HTTP 400 cuja mensagem nomeia uma versão. - Outras respostas de provedor diferentes de 200 levantam
SignatureFailedExceptionno AWS e no GCP, eAzureKeyVaultExceptionno Azure. - Uma falha de transporte PSR-18 durante a assinatura mapeia para
SignatureFailedExceptioncom a exceção do cliente preservada como o throwable anterior. AzureKeyVaultSignersem token de acesso e sem credenciais de service principal levantaAzureKeyVaultExceptionantes de qualquer chamada ao vault. Uma aquisição de token do Azure AD que falha também levantaAzureKeyVaultException.AzureKeyVaultSignervalida o nome do vault, o nome da chave, a versão de chave e o tenant id contra as gramáticas publicadas do Azure no ponto de estrangulamento da requisição. Um valor que carrega caracteres estruturais de URL falha de forma fail-closed comAzureKeyVaultException.GcpKmsSignersem um bearer token OAuth2 levantaSignatureFailedException; a aquisição do token é responsabilidade do chamador.- Uma resposta de provedor que não é JSON válido, ou que não tem o campo de assinatura, levanta
SignatureFailedException(Azure: um campovalueausente levantaAzureKeyVaultException). - Um campo de assinatura do provedor que falha na decodificação base64 levanta
SignatureFailedExceptionno AWS e no GCP, eAzureKeyVaultExceptionno Azure. - Nenhum adaptador
SigningStrategyparaGcpKmsSigneré distribuído no 3.1.0. O signer do GCP é consumido diretamente através do contratoKmsSignerInterface.
Comportamento em modo FIPS
Seção intitulada “Comportamento em modo FIPS”AwsKmsConfig::withFipsEndpoint() roteia as requisições para o endpoint kms-fips da região. O status de validação FIPS desse endpoint é uma propriedade da AWS, não do NextPDF. AzureKeyVaultConfig e GcpKmsConfig não expõem nenhum helper dedicado de endpoint FIPS no 3.1.0. O cálculo do digest roda em processo com a função PHP hash() e não é, ele mesmo, um módulo validado. O NextPDF Pro pode operar contra uma fronteira KMS ou HSM validada por FIPS, mas o NextPDF não é um módulo criptográfico validado por FIPS e não faz nenhuma alegação de certificação FIPS.
Conformidade
Seção intitulada “Conformidade”| Alegação | Padrão | Cláusula |
|---|---|---|
| A estratégia assina os atributos assinados codificados em DER; o digest de entrada da assinatura do CMS cobre a codificação DER completa de SignedAttrs. | RFC 5652 | §5.4 |
| SignedAttributes são codificados em DER e carregam content-type e message-digest no mínimo; signatureAlgorithm identifica o algoritmo do signer. | RFC 5652 | §5.3 |
| Os bytes de assinatura retornados são codificados como um OCTET STRING e carregados no campo de assinatura do SignerInfo. | RFC 5652 | §5.5 |
| O messageImprint de um carimbo de tempo de assinatura faz o hash do valor de assinatura do SignerInfo (superfície B-T adjacente, não estes signers). | RFC 3161 | Appendix A |
Todas as cláusulas são parafraseadas; o NextPDF não reproduz texto normativo. Estas são declarações de capacidade, não certificações. O NextPDF não detém nenhuma certificação e não concede nenhuma. Se uma assinatura produzida verifica ou não é decisão do verificador contra suas próprias âncoras de confiança e política; os signers retornam os bytes de assinatura e não asseguram nenhum resultado confiável. A custódia da chave, a proteção da chave e a validação de algoritmo do lado do provedor são propriedades do KMS configurado, não do NextPDF.
Notas de desenvolvimento
Seção intitulada “Notas de desenvolvimento”- Disponibilidade dentro do pacote Pro:
AwsKmsSignerdesde 1.9.0,AzureKeyVaultSignerdesde 2.0.0,GcpKmsSignereKmsSignerInterfacedesde 2.1.0. Todos são atuais nonextpdf/pro3.1.0. - Os signers dependem apenas de PSR-18, PSR-17 e PSR-3. Nenhum SDK da AWS, Azure ou Google é necessário ou empacotado.
- Sonde
supportsAlgorithm()antes de assinar para que um provedor incompatível seja rejeitado no momento da seleção, não no meio da sessão. - Os campos de credencial são injetados pelo construtor e marcados como parâmetros sensíveis. As mensagens de log carregam apenas campos estruturais; nenhuma credencial, token ou conteúdo de documento é gravado nos logs.
- Fixe as versões de chave explicitamente em implantações reguladas. Os padrões de resolução por alias (AWS) e de versão habilitada mais recente (Azure) são convenientes, mas não são determinísticos entre rotações.
- Drivers de terceiros implementam
KmsSignerInterfacee devem usar namespace no seuproviderId()para evitar colisões com os identificadores embutidos reservados.
Veja também
Seção intitulada “Veja também”- Assinatura com Cloud KMS (capacidade) — a página de guia prático: configuração, ajustes e a fronteira de custódia da chave.
- Segurança — Referência Detalhada —
RemoteSigningSession,SequentialSigner, a superfície PAdES B-B/B-T e o contratoSigningStrategy. - Assinatura — Referência Detalhada (Enterprise) — a fronteira do produtor de longo prazo B-LT/B-LTA.
- Segurança / Assinatura (Core) — o signer CMS do Core e os contratos que esta superfície estende.
Fronteira de publicação
Seção intitulada “Fronteira de publicação”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 mecanismos, nomes de arquivos de runbook e prefixos de ticket estão fora de escopo.