You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

6.9 KiB

Plan: firma de autor en Go (spec v0.11, entrega 2 del formato 3)

1 de octubre de 2026. El autor pidió poder firmar cápsulas («no tengo opción de meter firmas en la página») y dio el visto bueno a empezar por el spec y Go. La base es la parte 2 del diseño del formato 3 (apartados 10 a 15), ya revisada. Se hace en la rama v0.11 de datekeys-go, que ya tiene la llave de palabras (5b3d2d4).

Por qué primero el spec y Go

  • El spec es el contrato: dice qué bytes se firman, cómo se verifica una firma y qué ve quien abre. Lo que no está en el spec no puede comprobarlo otra implementación.
  • Go es la implementación de referencia: escribe los vectores y las cápsulas de prueba que después tiene que reproducir TypeScript byte a byte, como en el formato 3.
  • La página va después, con su propio plan, y reutiliza esas pruebas.

Pasos

Paso Contenido Resultado
0 Borrador del spec v0.11: qué se firma (AUTHOR_MESSAGE), Ed25519 estricto, las claves dkauthor1…, los veredictos de la firma, la llave de palabras y la nota pública Texto para que lo apruebe el autor
1 ed25519strict: la verificación estricta, con código propio para lo que ed25519.Verify de Go acepta de más Los casos de «Taming the many EdDSAs» en ed25519_strict.json
2 authorkey: generar la clave, escribirla como dkauthor1… y DKAUTHOR-SECRET-KEY-1…, y guardarla en un fichero cifrado con contraseña (age scrypt, logN 16) Pruebas de ida y vuelta y de errores
3 Firmar en el escritor: payload_commit, control_commit, head_digest y la firma en el área de seguridad, verificada antes de escribir Una cápsula firmada que abre un lector de la v0.10, que muestra F1
4 Verificar en el lector: los veredictos de la firma, y la comparación con la clave que se espera Firmas válidas, alteradas, quitadas, rehechas y trasplantadas
5 CLI: author keygen, author public, encrypt -sign y decrypt -expect-author Prueba de ida y vuelta con la CLI
6 Datos de prueba: el fixture format3_signed, statements.json y las mutaciones de la firma Lo que comprobará TypeScript
7 Documentación, check.sh, revisión adversarial y, con permiso del autor, el tag spec-v0.11 Rama lista

Queda para después la verificación por un tercero (statement export|verify, apartado 13), que no hace falta para firmar y comprobar firmas.

Cambio tras hablar con el autor (01-10)

El autor quiere que se sepa quién firma: con un certificado reconocido (FNMT, DNIe), firmado fuera de la página con su aplicación de firma.

  • Dos tipos de firma. alg 1, con una clave propia Ed25519 (dkauthor1…), como en el diseño. alg 2, una firma CAdES separada, la que produce AutoFirma, con el certificado X.509 de la persona: la página da el AUTHOR_MESSAGE como fichero, la persona lo firma fuera y carga la firma.
  • Escritura en dos tiempos. El escritor prepara la cápsula (sorteos, head y compromisos), devuelve AUTHOR_MESSAGE, espera la firma y entonces escribe. Los secretos solo viven en memoria entre los dos tiempos.
  • Área mayor. 512 bytes no caben una firma CAdES con su cadena. La v0.11 fija un área mayor, por ejemplo 16 KiB, la misma para toda cápsula, firmada o no (§29.2, hallazgo 5).
  • Verificación. DateKeys comprueba la firma y enseña el titular del certificado. La validez legal (cadena de confianza, revocación) la dan VALIDe o AutoFirma, a los que la página exporta la firma y el mensaje.
  • Sello de tiempo RFC 3161 de una autoridad cualificada (seal_type 2), dentro de la firma (CAdES-T) o pedido aparte, en lugar del servicio propio de la entrega 3.

Las aplicaciones (01-10)

DateKeys tendrá aplicación móvil, de escritorio (macOS, Windows y Linux), de línea de órdenes y la web. Todas escriben y leen la misma cápsula firmada. Lo que cambia es cómo consigue cada una la firma con certificado:

Aplicación Cómo firma con certificado
Web Fuera, con la aplicación de firma de la persona (AutoFirma), y carga la firma
Escritorio Con el certificado del sistema o de la tarjeta: almacén de Windows, llavero de macOS, PKCS#11 en Linux
Móvil Con el certificado importado en la app, o con el DNIe por NFC
CLI Con un fichero .p12 o la tarjeta (PKCS#11)

Por eso:

  • la API del escritor, en Go y en TypeScript, trabaja en dos tiempos, preparar y escribir con la firma, con un firmante que aporta cada aplicación;
  • la firma con certificado es CMS/CAdES estándar (SignedData separado sobre AUTHOR_MESSAGE), que todas esas plataformas producen de serie;
  • la librería de Go sirve para la CLI, el escritorio y el móvil (compilada para Android e iOS), y la de TypeScript para la web.

Decisiones del autor

  1. Dónde se guarda la clave secreta de autor. El diseño propone un fichero cifrado con contraseña. Como con la llave de palabras, podría poder guardarse también como palabras. Pero a diferencia de esa llave, la clave de autor es una sola para todas tus cápsulas, así que unas palabras flojas la exponen todas a la vez. Recomendación: fichero cifrado y, como alternativa, 12 palabras generadas al azar, nunca elegidas por la persona.
  2. Una sola firma por cápsula. El diseño deja un único hueco de firma, ampliable más adelante sin cambiar el formato. Recomendación: así.

Otras novedades de la v0.11 (01-10)

  • Nota pública. Un texto corto que se ve antes de la fecha, para saber qué es cada cápsula: una extensión no crítica de PUBLIC_HEADER, registrada en §72, de hasta 1 KiB y con las reglas de texto de §29.6. Un lector de la v0.10 la ignora y abre la cápsula igual.
    • Antes de la fecha no está comprobada: cualquiera puede fabricar una cápsula con la nota que quiera. La página y la CLI la muestran como nota de quien la creó, sin comprobar.
    • Al abrir, header_binding la ata a la cápsula, y la firma la cubre a través de control_commit. Cambiarla después rompe la cápsula.
  • La nota y la fecha, también en la .dkk, como pidió el autor, en una extensión no crítica (§44), para reconocer una llave suelta.
    • Es informativa, porque nada la ata a la cápsula. La .dkk se empareja con su cápsula por capsule_id y capsule_digest, que ya escriben Go y TypeScript, nunca por la nota.
    • Si la cápsula y la llave traen notas distintas, manda la de la cápsula y se avisa de la diferencia.
  • Código: en Go, las dos extensiones y -note en la CLI, con el paso 5; en la página, con su propio plan.
  • Ficheros fuera de la cápsula, propuesta pendiente de que el autor la confirme. Cada fichero iría dentro, como hoy, o fuera (IPFS, Drive, una URL), cifrado con la misma clave, con su hash, su tamaño y sus direcciones en una extensión crítica del head. Sus riesgos: que el fichero dure, que se pueda borrar antes de la fecha, que el cifrado quede público y que la web no pueda descargarlo de cualquier sitio.

Powered by TurnKey Linux.