Pro edición
Firma con KMS en la nube — Referencia detallada
De un vistazo
Sección titulada «De un vistazo»Esta página es la referencia a nivel de contrato de la superficie de firma con KMS en la nube de NextPDF Pro. La superficie consta de una interfaz de proveedor de servicios, NextPDF\Pro\Security\Signing\Kms\KmsSignerInterface, y tres firmadores de proveedor: AwsKmsSigner, AzureKeyVaultSigner y GcpKmsSigner. Dos adaptadores, AwsKmsSigningStrategy y AzureKeyVaultSigningStrategy, conectan un firmador con el contrato SigningStrategy de Pro. Cada firmador envía únicamente un digest de mensaje a su proveedor a través de HTTP PSR-18. La clave privada y el documento nunca cruzan el límite. Esta página expone la API pública, el contrato de comportamiento observable y los modos de fallo tipados. La orquestación de sesión (RemoteSigningSession, SequentialSigner) y el sellado de tiempo (PadesBtTimestamper) residen en sus propias páginas.
Disponibilidad y licencias
Sección titulada «Disponibilidad y licencias»Esta capacidad se distribuye en NextPDF Pro (nextpdf/pro) y se activa con un sobre de licencia de nivel Pro. Un despliegue sin ese derecho no carga las clases de la capacidad. Compara ediciones y obtén una licencia.
Superficie de la API pública
Sección titulada «Superficie de la API pública»| Símbolo | Parámetros | Comportamiento por defecto | Devuelve | Lanza o falla con | Notas |
|---|---|---|---|---|---|
KmsSignerInterface | — | Extiende el contrato HsmSignerInterface de Core | — | — | SPI para drivers de KMS y HSM; ids integrados reservados: aws-kms, azure-keyvault, gcp-kms, pkcs11, openssl-cli |
KmsSignerInterface::providerId() | ninguno | Clave estable de búsqueda en el registro | non-empty-string | — | Los drivers de terceros deben espaciar por nombre su identificador |
KmsSignerInterface::signWithVersion() | $data, $algorithm = 'sha256WithRSAEncryption', $keyVersion = null | Una versión de clave null recae en el valor por defecto del proveedor | octetos de firma string: RSA tal como los devuelve el proveedor (colocados directamente en SignerInfo.signature), ECDSA como DER ECDSA-Sig-Value según las reglas de CMS | KeyManagementException, UnsupportedAlgorithmException, SignatureFailedException | La semántica de null difiere por proveedor; véase el contrato de comportamiento |
KmsSignerInterface::supportsAlgorithm() | string $algorithm | Sondeo de capacidad; no realiza E/S | bool | — | Se invoca antes de la selección del proveedor |
KmsSignerInterface::supportedAlgorithms() | ninguno | Lista los nombres al estilo OpenSSL que acepta el proveedor | list<non-empty-string> | — | — |
AwsKmsSigner | constructor: AwsKmsConfig, cert DER, cadena DER, cliente PSR-18, fábricas PSR-17, logger PSR-3 | El algoritmo por defecto es KmsSigningAlgorithm::RsaPkcs1Sha256 | — | véanse los métodos | final; PROVIDER_ID = 'aws-kms' |
AwsKmsSigner::create() | id de clave, cert DER, dependencias PSR, cadena opcional, config, logger | Construye AwsKmsConfig::fromEnvironment($keyId) cuando $config es null | self | — | Lee las variables de entorno estándar AWS_* |
AwsKmsSigner::withAlgorithm() | KmsSigningAlgorithm $algorithm | Devuelve un clon modificado | self | — | Debe coincidir con el tipo de clave aprovisionada en AWS KMS |
AwsKmsSigner::sign() | $data, $algorithm = 'sha256WithRSAEncryption' | Delega en signWithVersion($data, $algorithm, null) | string | como signWithVersion() | Ruta del contrato heredado de Core con dos argumentos |
AzureKeyVaultSigner | constructor: AzureKeyVaultConfig, cert DER, cadena DER, cliente PSR-18, fábricas PSR-17, logger PSR-3 | El algoritmo por defecto es AzureSigningAlgorithm::Rs256; un token de acceso de config siembra el token bearer | — | véanse los métodos | final; PROVIDER_ID = 'azure-keyvault' |
AzureKeyVaultSigner::create() | nombre del vault, nombre de la clave, cert DER, dependencias PSR, cadena opcional, config, logger | Construye AzureKeyVaultConfig::fromEnvironment() cuando $config es null | self | — | Admite un token pre-obtenido o credenciales de service principal |
AzureKeyVaultSigner::withAlgorithm() | AzureSigningAlgorithm $algorithm | Devuelve un clon modificado | self | — | Las claves RSA usan valores RS/PS; las claves EC usan valores ES |
GcpKmsSigner | constructor: GcpKmsConfig, cert DER, cadena DER, cliente PSR-18, fábricas PSR-17, logger PSR-3 | El algoritmo por defecto es GcpKmsSigningAlgorithm::RsaSignPkcs1_2048Sha256 | — | véanse los métodos | final; PROVIDER_ID = 'gcp-kms', API_VERSION = 'v1' |
GcpKmsSigner::create() | id de proyecto, ubicación, key ring, crypto key, cert DER, dependencias PSR, cadena opcional, config, logger | Construye GcpKmsConfig::fromEnvironment() cuando $config es null | self | — | La adquisición del token bearer se delega en el invocador |
GcpKmsSigner::withAlgorithm() | GcpKmsSigningAlgorithm $algorithm | Solo vista previa en tiempo de configuración; el nombre de cable por llamada prevalece en el momento de firmar | self | — | El tamaño de clave lo fija la CryptoKeyVersion aprovisionada |
AwsKmsSigningStrategy | constructor: AwsKmsSigner $signer | Síncrono; isAsync() devuelve false | — | Propaga las excepciones del firmador envuelto | Adaptador para RemoteSigningSession::complete() |
AzureKeyVaultSigningStrategy | constructor: AzureKeyVaultSigner $signer | Síncrono; isAsync() devuelve false | — | Propaga las excepciones del firmador envuelto | Adaptador para RemoteSigningSession::complete() |
KmsSigningAlgorithm | enum, 9 casos (RSA PKCS#1, RSA-PSS, ECDSA; SHA-256/384/512) | — | Valores de cable SigningAlgorithm de AWS KMS | InvalidArgumentException desde fromOpenSslName() | resolveForWireName() preserva el digest PSS configurado |
AzureSigningAlgorithm | enum, 9 casos (RS256…ES512) | — | Valores al estilo JWA de Azure Key Vault | InvalidArgumentException desde fromOpenSslName() | isEcdsa() marca los valores cuya salida necesita conversión a DER |
GcpKmsSigningAlgorithm | enum, 10 casos (EC P-256/P-384, RSA PKCS#1, RSA-PSS) | — | Valores de algoritmo de CryptoKeyVersion de GCP | UnsupportedAlgorithmException desde fromOpenSslName() | La resolución del nombre de cable elige el menor tamaño de clave coincidente |
Firmas de los puntos de entrada
Sección titulada «Firmas de los puntos 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 comportamiento
Sección titulada «Contrato de comportamiento»Resolución del contrato
Sección titulada «Resolución del contrato»KmsSignerInterface extiende el contrato HsmSignerInterface de Core. Añade providerId(), el signWithVersion() consciente de la versión de clave, y los sondeos de capacidad supportsAlgorithm() y supportedAlgorithms(). El sign() heredado de dos argumentos delega en signWithVersion() con una versión de clave null en los tres firmadores. getCertificateDer(), getCertificateChainDer() y getPublicKeyAlgorithm() se implementan a partir del material suministrado en el constructor. Los sondeos de capacidad no realizan E/S. Cada firmador expone además los accesores getSigningAlgorithm() y getConfig() para inspección.
Transmisión solo del digest
Sección titulada «Transmisión solo del digest»Cada firmador hace hash de $data localmente con el digest del algoritmo resuelto y transmite únicamente ese digest. AWS recibe un digest en base64 con MessageType: DIGEST. Azure recibe un digest en base64url en el cuerpo de la petición de firma. GCP recibe un digest en base64 en el campo de digest específico del algoritmo. Los bytes del documento nunca aparecen en una petición del proveedor. Todo el transporte usa un cliente HTTP PSR-18 estándar sobre el endpoint HTTPS del proveedor; no interviene ningún SDK del proveedor en la nube.
Resolución de la versión de clave
Sección titulada «Resolución de la versión de clave»signWithVersion() valida el argumento de versión de clave fail-closed antes de construir cualquier petición. Un valor que no supera la gramática del proveedor lanza KeyManagementException e impide la inyección de segmento de URL o de KeyId.
| Proveedor | Versión de clave null | Cadena vacía | Gramática de sobrescritura |
|---|---|---|---|
AwsKmsSigner | Usa AwsKmsConfig::$keyId; un alias o ARN se resuelve a la clave actual del lado del proveedor | Rechazada | UUID (con o sin guiones), alias/<name>, o un ARN de clave/alias de KMS |
AzureKeyVaultSigner | Usa la versión de clave configurada; un valor de config vacío selecciona la última versión habilitada del lado del servidor | Rechazada | Identificador hexadecimal de 32 caracteres |
GcpKmsSigner | Usa la versión anclada en GcpKmsConfig; sin ninguna anclada, lanza KeyManagementException | Rechazada | Id decimal de CryptoKeyVersion, solo dígitos |
GCP no tiene una primitiva de “versión activa” del lado del servidor. El endpoint de firma asimétrica opera únicamente sobre un recurso cryptoKeyVersions/{n} específico, de modo que una versión siempre debe ser resoluble.
Resolución de algoritmos
Sección titulada «Resolución de algoritmos»La capa de estrategia reenvía un nombre de cable al estilo OpenSSL. AWS y Azure aceptan siete nombres de cable (PKCS#1 y ECDSA en SHA-256/384/512, más RSASSA-PSS). GCP acepta cinco (sha256WithRSAEncryption, sha512WithRSAEncryption, RSASSA-PSS, ecdsa-with-SHA256, ecdsa-with-SHA384). El nombre de cable RSASSA-PSS no codifica un digest, por lo que es ambiguo respecto al digest. AwsKmsSigner lo resuelve a través de KmsSigningAlgorithm::resolveForWireName(), que preserva el digest de la variante PSS configurada. AzureKeyVaultSigner confía en la variante PSS configurada para el nombre ambiguo. Lanza UnsupportedAlgorithmException si un digest PSS resuelto divergiera del configurado. GcpKmsSigner vuelve a resolver el enum a partir del nombre de cable en cada llamada; withAlgorithm() en GCP es una vista previa en tiempo de configuración y no cambia el comportamiento en el momento de firmar. Un nombre de cable no admitido lanza UnsupportedAlgorithmException antes de cualquier llamada de red. En AwsKmsSigner y GcpKmsSigner, una llamada de firma actualiza el valor que luego reporta getSigningAlgorithm() al algoritmo resuelto por llamada. En AzureKeyVaultSigner, la resolución es local a la llamada y el valor configurado sigue siendo autoritativo.
Normalización de la firma
Sección titulada «Normalización de la firma»AWS y GCP devuelven las firmas en la forma que consume CMS: los octetos de firma RSA van a SignerInfo.signature sin cambios, y ECDSA llega codificado en DER. Azure devuelve ECDSA en formato IEEE P1363 en crudo (r||s), que el firmador convierte a un DER ECDSA-Sig-Value antes de devolverlo.
Integración con CMS y adyacencia
Sección titulada «Integración con CMS y adyacencia»Un adaptador SigningStrategy firma los atributos firmados codificados en DER que suministra la sesión. Con atributos firmados presentes, la entrada de firma de CMS es el digest de la codificación DER completa del valor SignedAttrs — RFC 5652 §5.4. Los métodos getSignatureAlgorithmOid() y getDigestAlgorithm() del adaptador alimentan los campos signatureAlgorithm y digestAlgorithm del SignerInfo — RFC 5652 §5.3. Los bytes devueltos pasan a ser el OCTET STRING de firma del SignerInfo — RFC 5652 §5.5. El ensamblado de CMS, el manejo de ByteRange y el ciclo de vida de la sesión pertenecen a RemoteSigningSession; los flujos multiparte pertenecen a SequentialSigner. Un sello de tiempo de firma PAdES B-T, cuyo messageImprint hace hash del valor de firma del SignerInfo — RFC 3161 Appendix A —, lo aplica PadesBtTimestamper, no estos firmadores. Los tres se documentan en la referencia detallada de seguridad de Pro.
Casos límite y modos de fallo
Sección titulada «Casos límite y modos de fallo»- Una versión de clave de cadena vacía se rechaza en los tres proveedores. Pasa
nullpara heredar el valor por defecto configurado. - Una versión de clave malformada se rechaza antes de construir cualquier petición, con el valor infractor nombrado en la excepción.
AwsKmsSignercon unAwsKmsConfig::$keyIdvacío y una versión de clavenulllanzaKeyManagementException.- Las respuestas del proveedor que indican un fallo de gestión de claves se mapean a
KeyManagementException: AWSNotFoundException,DisabledException,KeyUnavailableException,InvalidKeyUsageException, o HTTP 404; Azure HTTP 404,KeyNotFound,KeyDisabled, oKeyNotActive; GCP HTTP 404 o 409,NOT_FOUND,FAILED_PRECONDITION, o un HTTP 400 cuyo mensaje nombra una versión. - Otras respuestas del proveedor distintas de 200 lanzan
SignatureFailedExceptionen AWS y GCP, yAzureKeyVaultExceptionen Azure. - Un fallo de transporte PSR-18 durante la firma se mapea a
SignatureFailedExceptioncon la excepción del cliente preservada como el throwable previo. AzureKeyVaultSignersin token de acceso y sin credenciales de service principal lanzaAzureKeyVaultExceptionantes de cualquier llamada al vault. Una adquisición fallida de token de Azure AD también lanzaAzureKeyVaultException.AzureKeyVaultSignervalida el nombre del vault, el nombre de la clave, la versión de la clave y el id de tenant contra las gramáticas publicadas de Azure en el punto de estrangulamiento de la petición. Un valor que porte caracteres estructurales de URL falla en modo cerrado conAzureKeyVaultException.GcpKmsSignersin token bearer OAuth2 lanzaSignatureFailedException; la adquisición del token es responsabilidad del invocador.- Una respuesta del proveedor que no es JSON válido, o a la que le falta el campo de firma, lanza
SignatureFailedException(Azure: la falta de un campovaluelanzaAzureKeyVaultException). - Un campo de firma del proveedor que no supera la decodificación base64 lanza
SignatureFailedExceptionen AWS y GCP, yAzureKeyVaultExceptionen Azure. - En 3.1.0 no se distribuye ningún adaptador
SigningStrategyparaGcpKmsSigner. El firmador de GCP se consume directamente a través del contratoKmsSignerInterface.
Comportamiento en modo FIPS
Sección titulada «Comportamiento en modo FIPS»AwsKmsConfig::withFipsEndpoint() enruta las peticiones al endpoint kms-fips de la región. El estado de validación FIPS de ese endpoint es una propiedad de AWS, no de NextPDF. AzureKeyVaultConfig y GcpKmsConfig no exponen ningún helper de endpoint FIPS dedicado en 3.1.0. El cálculo del digest se ejecuta en proceso con la función hash() de PHP y no es en sí mismo un módulo validado. NextPDF Pro puede operar contra un límite de KMS o HSM validado por FIPS, pero NextPDF no es un módulo criptográfico validado por FIPS y no realiza ninguna afirmación de certificación FIPS.
Conformidad
Sección titulada «Conformidad»| Afirmación | Estándar | Cláusula |
|---|---|---|
| La estrategia firma los atributos firmados codificados en DER; el digest de entrada de firma de CMS cubre la codificación DER completa de SignedAttrs. | RFC 5652 | §5.4 |
| SignedAttributes están codificados en DER y portan content-type y message-digest como mínimo; signatureAlgorithm identifica el algoritmo del firmador. | RFC 5652 | §5.3 |
| Los bytes de firma devueltos se codifican como un OCTET STRING y se portan en el campo de firma del SignerInfo. | RFC 5652 | §5.5 |
| El messageImprint de un sello de tiempo de firma hace hash del valor de firma del SignerInfo (superficie B-T adyacente, no estos firmadores). | RFC 3161 | Appendix A |
Todas las cláusulas están parafraseadas; NextPDF no reproduce texto normativo. Son declaraciones de capacidad, no certificaciones. NextPDF no posee ninguna certificación ni la otorga. Si una firma producida verifica o no es la decisión del verificador frente a sus propios anclajes de confianza y su política; los firmadores devuelven bytes de firma y no afirman ningún resultado de confianza. La custodia de la clave, la protección de la clave y la validación de algoritmos del lado del proveedor son propiedades del KMS configurado, no de NextPDF.
Notas de desarrollo
Sección titulada «Notas de desarrollo»- Disponibilidad dentro del paquete Pro:
AwsKmsSignerdesde 1.9.0,AzureKeyVaultSignerdesde 2.0.0,GcpKmsSigneryKmsSignerInterfacedesde 2.1.0. Todos están vigentes ennextpdf/pro3.1.0. - Los firmadores dependen únicamente de PSR-18, PSR-17 y PSR-3. No se requiere ni se incluye ningún SDK de AWS, Azure o Google.
- Sondea
supportsAlgorithm()antes de firmar para que un proveedor incompatible se rechace en el momento de la selección, no a mitad de sesión. - Los campos de credenciales se inyectan por constructor y se marcan como parámetros sensibles. Los mensajes de log portan solo campos estructurales; ningún credencial, token o contenido de documento se escribe en los logs.
- Ancla las versiones de clave explícitamente en despliegues regulados. Los valores por defecto de resolución de alias (AWS) y de última habilitada (Azure) son cómodos pero no deterministas entre rotaciones.
- Los drivers de terceros implementan
KmsSignerInterfacey deben espaciar por nombre suproviderId()para evitar colisiones con los identificadores integrados reservados.
Véase también
Sección titulada «Véase también»- Firma con KMS en la nube (capacidad) — la página de guía práctica: configuración, ajustes y el límite de custodia de claves.
- Seguridad — Referencia detallada —
RemoteSigningSession,SequentialSigner, la superficie PAdES B-B/B-T y el contratoSigningStrategy. - Firma — Referencia detallada (Enterprise) — el límite del productor a largo plazo B-LT/B-LTA.
- Seguridad / Firma (Core) — el firmador CMS de Core y los contratos que esta superficie extiende.
Límite de publicación
Sección titulada «Límite de publicación»Esta página documenta únicamente el comportamiento observable externamente y la superficie de la API pública admitida. Las rutas de espacio de nombres internas, las clases auxiliares, las tablas de mecanismos, los nombres de archivo de runbook y los prefijos de ticket quedan fuera de alcance.