REVIEWITDocumentación
Esta página se genera a partir de REVIEWIT_SignOff_Artifact/SPEC-Verification-v1.md — no se corrige a mano.Corregir el contrato corrige la página. Modificarla aquí se perdería en la próxima generación.GENERADA EL 5 septiembre 2026 · REVIEWIT-SignOff-Verification/1 · 242451e5
Referencia generadaAl día · generada el 5 septiembre 2026

Verificar una prueba sin conexión

Traducción automática, aún no revisadaEsta página fue traducida por un modelo a partir de la versión francesa, que es la que da fe. Leer la versión francesa.

01Lo que permite este documento #sec_e0af9bcf

REVIEWIT produce, en cada firma, una atestación sellada de la que se puede extraer un paquete de verificación: un archivo que contiene todo lo necesario para volver a hacer la demostración en otro lugar.

Este documento es la especificación completa de este formato. Se publica por una razón precisa: permitir a un tercero verificar una prueba sin nosotros, e incluso sin creernos. Describe con bastante exactitud la canonización, la construcción de árboles y la verificación de las pruebas de inclusión para que un auditor, una dirección de sistemas de información o una empresa independiente pueda escribir su propio verificador y obtener el mismo veredicto que el nuestro.

Es la forma más alta de la garantía que anuncia REVIEWIT. Una plataforma que dijera « confíen en nosotros, está sellado » pediría exactamente lo que este documento hace innecesario.

02A quién se dirige #sec_c1bc9732

A un lector técnico: la persona que verificará una prueba, o la que escribirá la herramienta que la verifica. No es necesario para leer un informe de auditoría, ni para utilizar REVIEWIT.

Un auditor que desee obtener solo un veredicto no tiene que leer este texto: la pantalla « Verificar una prueba » del Centro de trabajo y la herramienta de línea de comandos aplican este contrato, sin desviaciones. Este documento existe para aquellos que se niegan a confiar en uno u otro — y tienen razón en poder hacerlo.

03Lo que necesita #sec_48297a56

Cuatro elementos, y no provienen del mismo lugar:

  1. El paquete de verificación — el archivo en sí. Se le entrega con la prueba que se le opone, o lo descarga desde REVIEWIT.
  2. Un verificador — el que escribe a partir de este documento, o el que REVIEWIT pone a disposición. Los dos deben dar el mismo veredicto; si divergen, es un defecto, y nos concierne.
  3. El llavero público de la autoridad — servido por este portal en la dirección /.well-known/seal-keyring.json, y entregado con el anexo de seguridad de su contrato. Lleva las claves públicas con las que se controla la firma del sello, y solo ella. Todo lo demás — la huella, las raíces de Merkle, el encadenamiento, la prueba de inclusión — se verifica sin ninguna clave, desde el único archivo.
  4. La huella de la clave raíz — llevada por el anexo de seguridad firmado con su contrato. Es ella, y solo ella, la que establece que el llavero que ha descargado es el nuestro (§8.3).

04Lo que el archivo solo establece, y lo que no establece #sec_192edcae

Sin llavero, un paquete sigue siendo completamente verificable en su coherencia interna: que el manifiesto produce bien la huella anunciada, que las listas producen bien las raíces atestadas, que un elemento dado figura bien en el perímetro sellado.

Lo que el archivo solo no establece, es que este contenido ha sido sellado por nosotros. Un paquete puede declararse sellado sin estarlo: esta declaración no vale nada mientras la firma de la autoridad no haya sido controlada con su clave pública. Un verificador conforme debe, por lo tanto, distinguir estos dos constats y nunca presentar el segundo como adquirido a partir del primero.

051. Canonización, versión 1 #sec_53b1cef4

Un documento canónico es un JSON UTF-8 sin BOM, sin espacios ni retornos de carro, tal que :

  1. las claves de un objeto están ordenadas por orden ordinal de los puntos de código ;
  2. las cadenas están normalizadas Unicode NFC ; solo ", \ y los caracteres de control están escapados ; el no-ASCII no está escapado ;
  3. los únicos números son enteros firmados de 64 bits ; ningún flotante ; una proporción se expresa por diez mil ;
  4. los instantes están en tiempo universal, en formato yyyy-MM-ddTHH:mm:ss.ffffffZ — seis decimales, el séptimo truncado ; las fechas civiles en formato yyyy-MM-dd ;
  5. un valor no aplicable está ausente ; no existe ni null, ni cadena vacía en lugar de ausencia ;
  6. las secuencias de octetos están en hexadecimal minúscula.

Un documento que contenga un null, un flotante o una clave duplicada no es un documento canónico y es rechazado.

062. Hashing #sec_9d21b1bf

SHA-256, identificador "SHA-256" portado en cryptography.hash del manifiesto.

073. Esquema de árbol, versión 1 #sec_3b2d707a

ElementoDefinición
Prefijos de dominiohoja 0x00, nodo 0x01, árbol vacío 0x02, raíz 0x03
HojaH(0x00 ‖ azar ‖ contenido) — el azar hace 32 octetos, propio de cada hoja
NodoH(0x01 ‖ izquierda ‖ derecha)
Nivel imparel nodo huérfano es promovido tal cual al nivel superior, nunca duplicado
Compromisoobjeto canónico `{"domain":{"empty":2,"leaf":0,"node":1,"root":3},"hash":"SHA-256","leafCount":n,"schema":1,"tree":"scope""decisions"}`
Raíz publicadaH(0x03 ‖ compromiso ‖ raíz bruta) para n ≥ 1
Raíz del lote vacíoH(0x02 ‖ compromiso) con leafCount = 0

Orden de las hojas. Clave compuesta (SHA-256(identidad), identidad), comparada octeto por octeto en lexicográfico no firmado, el segundo término desempatando solo las igualdades del primero. Dos identidades idénticas en un lote son un rechazo.

Dos árboles. scope : el contenido de la hoja es la identidad estable canónica {"criterion":…,"object":…,"type":…}. decisions : el contenido es la decisión canónica (§5). Mismo orden, misma posición para un mismo elemento.

Azar. Derivados por SEAL de la generación cryptography.secretGeneration, por (arbol, posición). El secreto no figura en ningún paquete.

084. Prueba de inclusión #sec_b535f3ee

{"commitment":{…},"content":hex,"path":[{"side":"left"|"right","sibling":hex} | {"promoted":true} …],"position":p,"root":hex,"salt":hex,"schema":1}

Verificación : recalcular la hoja, remontar el camino exigiendo en cada nivel exactamente lo que la estructura impone — un hermano del lado correcto cuando el índice tiene un vecino, una promoción cuando el índice es el último de un nivel impar —, luego H(0x03 ‖ compromiso ‖ nodo) y comparar con la raíz atestada. Un camino más corto o más largo que la estructura es un rechazo.

095. Manifiesto, versión 1 #sec_9dbbc182

Bloques del objeto raíz (claves ordenadas): actors, context, cryptography, decisions, governance, header, qualification, scope, snapshot, statement.

  • header: attestation, canonicalization (1), complementRank, lot, originLot (ausente para el lote inicial), schema (1).
  • decisions[i]: actor, decidedAt, exceptionUntil, identity, justification, origin (human | defaultRule | systemClosure | nonDecidedUncovered), previous, rule (id, motive, version — presente si y sólo si el origen no es humano), verdict.
  • qualification: closure, conflictOfInterest, coverage (complete), decisionMode, origins (cuatro recuentos, calculados).
  • governance.indicators: los cuatro enteros con collected:true, o {"collected":false}.
  • cryptography: hash, preflight ({"state":"unavailable"} o referencia), secretGeneration, trees.scope y trees.decisions (commitment, root).

Forma sellada. La huella sellada —aquella que lleva el anclaje— es SHA-256 de la forma canónica donde scope y decisions son reemplazados por su compromiso {"count":n,"hash":SHA-256(lista canónica)}. Las listas sólo viajan en el paquete completo; las raíces de Merkle ya las comprometen.

106. Paquetes #sec_de906bc8

CampoCompletoPuntual
specificationREVIEWIT-SignOff-Verification/1idem
kindcompletepuntual
attestationforma selladaforma sellada
digestSHA-256(attestation)idem
scope.items, decisionslistas completas, en orden canónico—
salts.scope, salts.decisionstodos los azares, por posición—
proof—una prueba, con el azar de la única hoja revelada
sealing{"state":"unanchored"}; o anchored con domain, segment, rank, anchoredAt, seal:"pending"; o sealed con además seal.reference, seal.sealedAtidem

117. Procedimiento #sec_9a00ec24

  1. Releer el paquete como documento canónico (§1); rechazar si no.
  2. Verificar specification.
  3. Recalcular SHA-256(attestation) y compararlo con digest, y con la huella mantenida por otra parte en caso de ser necesario.
  4. Verificar header.schema, header.canonicalization, cryptography.hash.
  5. Completo: verificar los compromisos de las dos listas; verificar que en cada posición la decisión lleve la identidad del ítem; reconstruir cada árbol desde la lista y los azares (§3) y comparar raíz y leafCount con cryptography.trees.
  6. Puntual: verificar que la prueba apunte a la raíz y el leafCount atestiguados para su árbol; verificar la prueba (§4).
  7. Leer sealing.state y restituirlo tal cual: esta versión no verifica ni el anclaje ni el sello, y un paquete unanchored no es oponible.

Un paquete es válido cuando todos los controles ejecutados tienen éxito. Esto no establece que esté sellado.

128. Juego de llaves público y anclaje por llave raíz #sec_71a42b6e

El sello de un paquete se verifica con la llave pública de la autoridad, publicada en un juego de llaves: un archivo JSON, independiente de los paquetes, que el tercero posee.

{
  "keys": [ { "kid": "signing:1", "alg": "ecdsa-p256-sha256", "spki": "<DER SubjectPublicKeyInfo, base64>" } ],
  "attestation": {
    "version": "seal.keyring.v1",
    "count": 1,
    "digest": "<hex>",
    "alg": "ecdsa-p256-sha256",
    "rootKid": "keyring-root:1",
    "rootSpki": "<DER SubjectPublicKeyInfo de la racine, base64>",
    "signature": "<base64>"
  }
}

El paquete nombra su llave, el juego de llaves la proporciona. sealing.seal.keyId designa la entrada a emplear. Una entrada nunca es retirada de un juego de llaves: retirarla haría inverificables todas las pruebas que ha sellado.

8.1 Huella del contenido

Retener las entradas que llevan a la vez kid, alg y spki —una entrada incompleta no confiere ninguna llave y no entra en el cálculo. Ordenarlas por kid, en comparación ordinal sobre los puntos de código. Formar una línea por entrada, kid | alg | spki seguida de un salto de línea U+000A. La huella es el SHA-256 de la concatenación UTF-8 de estas líneas, en hexadecimal minúscula.

La fecha de creación de una entrada, si figura, no entra en el cálculo: es un instantáneo de visualización.

8.2 Vector firmado por la raíz

seal.keyring.v1|<nombre d'entrées retenues>|<empreinte du contenu>

Firmado en forma de texto, codificado en UTF-8, por la llave raíz, según attestation.alg. Las suites admitidas son las del sello: ecdsa-p256-sha256 (firma ASN.1 DER, RFC 3279) y rsa-pkcs1-sha256. Un algoritmo desconocido es un rechazo, nunca una admisión.

8.3 Lo que el tercero posee, y por qué la raíz

El ancla del dispositivo es la huella de la llave raíz —SHA-256 de su SubjectPublicKeyInfo DER, en hexadecimal minúscula— llevada por el anexo de seguridad que el cliente firma con su contrato.

Se refiere a la raíz, nunca al archivo. Un juego de llaves crece: cada rotación de llave de sellado le añade una entrada. Una huella del archivo caducaría a la primera rotación, y un auditor que posee el archivo correcto, caducado, vería caer una prueba auténtica. La raíz, ella, no cambia; el anexo firmado nunca se reabre.

8.4 Procedimiento de verificación de un juego de llaves

  1. Recalcular la huella del contenido (§8.1) y el número de entradas retenidas, y compararlas con attestation.digest y attestation.count. Recalcular primero, verificar la firma después: controlar la firma sobre la huella declarada dejaría pasar un juego de llaves cuyos llaves se han cambiado conservando el bloque firmado.
  2. Verificar attestation.signature sobre el vector (§8.2) con attestation.rootSpki.
  3. Comparar la huella de attestation.rootSpki con la que lleva el anexo.

Seis resultados, y sólo uno es oponible:

ResultadoLo que se establece
Juego de llaves ancladoFirma verificada y raíz conforme al anexo. Único estado oponible.
Firmado, raíz no controladaNinguna huella de anexo proporcionada: coherencia interna sólo —cualquiera puede firmar un juego de llaves con su propia raíz.
Firmado por otra raízEl archivo no es aquel que el anexo designa.
AlteradoEl contenido ya no produce la huella atestiguada.
Atestación inválidaLa raíz declarada no ha firmado este contenido.
No ancladoNingún bloque attestation —un juego de llaves anterior al dispositivo. No es una falta; es un archivo sin ancla.

Un juego de llaves no anclado siempre permite controlar un sello. Lo que no permite es establecer de dónde viene la llave pública empleada —y una firma verificada con una llave de procedencia desconocida no establece nada.

Esc
↑↓ navegar↵ abrirVer todos los resultados →