Skip to content

Firmar y luego cifrar, descifrar y luego verificar

Firma datos y cifra el resultado firmado en una sola operación, para que la firma viaje cifrada (un JWE cuyo texto en claro es un JWS), y recupera los datos solo cuando la firma se verifica.

Quién puede hacerlo

Una aplicación autenticada como actor criptográfico de tu tenant. Su token debe llevar el scope de la operación, y el actor debe tener concesiones de capacidad activas sobre las dos claves:

Operación Scope Concesiones de capacidad
Firmar y luego cifrar en una sola solicitud secure.signAndEncrypt SIGN sobre la clave de firma, ENCRYPT sobre la clave de cifrado
Descifrar y luego verificar en una sola solicitud secure.decryptAndVerify DECRYPT sobre la clave de descifrado, VERIFY sobre cada firmante interno
Firmar y luego cifrar un stream stream.signAndEncryptStream SIGN sobre la clave de firma, ENCRYPT sobre la clave de cifrado
Descifrar y luego verificar un stream stream.decryptAndVerifyStream DECRYPT sobre la clave de descifrado, VERIFY sobre cada firmante interno

Ningún rol de la consola realiza estas operaciones.

Antes de empezar

  • Existen dos claves distintas en el tenant: una que firma y otra que cifra. Cada clave debe servir para su propio tramo: una clave compuesta de firma puede firmar, una clave compuesta KEM puede cifrar. Consulta Crear una clave.
  • La aplicación puede obtener un token. Consulta Obtener un token de acceso para una aplicación.

Pasos

  1. Firma y luego cifra:
    • SDK de Java: sdk.signThenEncrypt(signKid, encryptKid, data) devuelve un SignEncryptResult. Para archivos, signThenEncryptFileCompact(signKid, encryptKid, input, output) o signThenEncryptFileStream(signKid, encryptKid, input, output).
    • CLI criptográfica: AnkaSecureCLI sign-encrypt-file --sign-kid <kid> --encrypt-kid <kid> --input-file <file> --output-file <file>, o sign-encrypt-file-stream con las mismas opciones para archivos grandes.
    • API: POST /api/v3/crypto/sign-encrypt con {"signKid", "encryptKid", "data"} y, de forma opcional, serialization y validityDays para la firma interna. Para un stream, POST /api/v3/crypto/stream/sign-encrypt con un cuerpo multipart/form-data, metadata antes de file.
  2. Descifra y luego verifica:
    • SDK de Java: sdk.decryptThenVerify(jwe) devuelve un DecryptVerifyResult; lee getDecryptedData() y getSignatureResults(). Para archivos, decryptThenVerifyFileCompact(input, output) o decryptThenVerifyFileStream(input, output).
    • CLI criptográfica: AnkaSecureCLI decrypt-verify-file --input-file <file> --output-file <file>, o decrypt-verify-file-stream para un artefacto de streaming.
    • API: POST /api/v3/crypto/decrypt-verify con {"jweToken": {...}}. Para un stream, POST /api/v3/crypto/stream/decrypt-verify con el encabezado multipart/mixed y las partes del texto cifrado.
  3. Si el JWE externo está dirigido a varias claves, nombra aquella con la que descifra tu actor: recipientKid, --recipient-kid o el argumento recipientKid de los métodos del SDK.
  4. En un descifrado y verificación en streaming, espera la parte del veredicto. El texto en claro llega antes; el verdict global es VALID solo cuando tanto la comprobación de integridad (gcmTagVerdict) como las firmas internas (signatureVerdict) son VALID. El SDK y la CLI escriben la salida solo entonces.

Qué ves cuando funcionó

Firmar y luego cifrar devuelve el JWE anidado, con los metadatos de firma y de cifrado informados por separado. Descifrar y luego verificar devuelve el texto en claro junto con una entrada de signatureResults por cada firma interna, cada una con su clave, su algoritmo, su versión de material y su veredicto. La operación de una sola solicitud no entrega texto en claro a menos que se verifiquen todas las firmas internas.

Si falla

Qué ves Causa Qué hacer
400 .../errors/invalid-input Las dos claves son la misma, una clave no sirve para su tramo (una clave de firma usada para cifrar, o al revés), o los datos no son Base64 válido Usa dos claves distintas, cada una del tipo correcto
400 .../errors/serialization-incompatible-with-timestamp Se pidió la serialización compacta para la firma interna y el tenant exige un sello de tiempo cualificado Pide JSON, u omite serialization
403 .../errors/forbidden Al token le falta el scope, o el actor no tiene ninguna concesión sobre una de las claves Pide a un administrador del tenant que revise los roles y las concesiones del actor
404 .../errors/not-found Una clave no existe Revisa los identificadores de clave
409 .../errors/invalid-key-state Una de las claves está en un estado que no permite la operación, por ejemplo revocada Usa claves activas
422 al descifrar y luego verificar Una firma interna no se verifica, el texto cifrado no supera su comprobación de integridad, o el token está mal formado. No se devuelve texto en claro No uses los datos
Un descifrado y verificación en streaming termina con el veredicto INVALID Se alteró el texto cifrado, una firma interna no se verifica, o el actor no puede verificar con un firmante interno Descarta la salida; el SDK lanza DecryptVerifyIntegrityException con el veredicto de cada firmante y no escribe ningún archivo
413 .../errors/payload-too-large Los datos superan el límite de una sola solicitud Usa la operación de streaming

Sin la consola

Estas operaciones no tienen pantalla en la consola.

Superficie Cómo
SDK de Java signThenEncrypt, signThenEncryptFileCompact, signThenEncryptFileStream, decryptThenVerify, decryptThenVerifyFileCompact, decryptThenVerifyFileStream en AuthenticatedSdk
CLI criptográfica AnkaSecureCLI sign-encrypt-file, decrypt-verify-file, sign-encrypt-file-stream, decrypt-verify-file-stream
API POST /api/v3/crypto/sign-encrypt (signThenEncrypt), POST /api/v3/crypto/decrypt-verify (decryptThenVerify), POST /api/v3/crypto/stream/sign-encrypt (signEncryptStream), POST /api/v3/crypto/stream/decrypt-verify (decryptVerifyStream)

Relacionado

Estas páginas están en inglés: