Vai al contenuto

Registro di trasparenza

Tutto ciò che firmiamo, in pubblico

Ogni firma di Content Credentials, ogni marca temporale e ogni risultato di verifica firmato che Kennmarq.com rilascia viene prima scritto in questo registro. Il registro può solo crescere, e firmiamo una radice che lo copre per intero ogni ora finché cresce, e comunque almeno una volta al giorno. Chiunque può verificare che la firma di un file vi sia presente, e che nulla sia mai stato rimosso, modificato o retrodatato.

Ultima radice firmata

Voci
563
Firmata
(radice 149)
Hash della radice
897c3b232864c2c9130f7d67a12815bb865d0ca08f4efec23f83e5b78f2fa893
ID della chiave
3b51f0f999b77a04bd96b2b86fa783237f5f33f29c55275a7e5a06ad7230829e
Firma
MEYCIQDvtHKEuzfherpaixgaZFQUw3aaS2FIuay/ETvcVGbgVQIhAJc6l/rUw38Yoi04yj1bKKbZyGIr5I24JaE4ezqbC5uB

Ora il registro contiene 563 voci. In JSON: https://api.kennmarq.com/v1/log/root

Cosa contiene

  • Firme: per ogni file marcato tramite l’API, l’identificativo del suo manifest e lo SHA-256 del file, della sua firma, del certificato di firma e della marca temporale contenuta nella firma. Per un file marcato in modalità locale, che non arriva mai a noi, il suo hard binding prende il posto del suo SHA-256.
  • Marche temporali: per ogni token del nostro server di marca temporale, il suo numero di serie, la sua ora, il suo SHA-256 e l’hash a cui si riferisce.
  • Ancoraggi del registro di audit: il registro di audit di ogni organizzazione è concatenato tramite hash; il suo ultimo hash finisce qui, sotto uno pseudonimo che solo i suoi membri possono riconoscere, così la sua storia non può essere riscritta senza che si veda.
  • Risultati di verifica firmati: per ogni risultato di POST /v1/verify che firmiamo, il suo SHA-256, lo SHA-256 del file verificato e l’ID della chiave del nostro verificatore.

Mai presenti: nomi o ID delle organizzazioni, nomi o contenuti dei file, ID delle filigrane, modelli, app o titoli, indirizzi o persone. Chi ha un file può trovarne la voce; nessun altro ricava alcuna informazione dal registro.

Verificalo in autonomia

  1. Trova la voce di un file tramite l’identificativo del suo manifest, o tramite l’header X-Log-Index che l’API ha restituito con il file: GET /v1/log/proof/urn:c2pa:… risponde con la voce e gli hash che la collegano a una radice firmata.
  2. Verifica che la voce corrisponda al file (il suo SHA-256, l’identificativo del suo manifest) e ricostruisci la prova risalendo fino alla radice.
  3. Verifica la firma della radice con la nostra chiave pubblica, qui sotto.
  4. Conserva le radici che hai visto. GET /v1/log/consistency dimostra che qualsiasi radice successiva inizia ancora con tutte le voci di una precedente.

Il riferimento API riporta i formati esatti e le poche righe di shell e Python che eseguono ogni verifica. L’albero è quello della RFC 9162 (Certificate Transparency), e le radici sono firmate come i tree head della RFC 6962, quindi si possono usare gli strumenti e le librerie esistenti.

Verifica l’ultima radice con OpenSSL (e jq)
curl -s "https://api.kennmarq.com/v1/log/key?format=pem" -o log-key.pem
curl -s "https://api.kennmarq.com/v1/log/root" -o root.json
printf '0001%016x%016x%s' "$(jq .timestamp root.json)" "$(jq .tree_size root.json)" \
  "$(jq -r .root_hash root.json)" | xxd -r -p > tree-head.bin
jq -r .signature root.json | base64 --decode > signature.der
openssl dgst -sha256 -verify log-key.pem -signature signature.der tree-head.bin

Radici recenti

Le dieci radici firmate più recenti
RadiceFirmataVociHash della radice
149563897c3b232864c2c9130f7d67a12815bb865d0ca08f4efec23f83e5b78f2fa893
148550533fa80cc9342b3b7d2a938e123583adaa3a3ff1e1f15a5e0c567b9285ae5c5c
147544cb537fb383038e50850a7e8ebdbab3e01ef879e50e161ff38666ba8ae6d8da76
146543f4b334fc696c7580c8dfd1cc72655e3470da10d61708f3fe861f3ddc3a92177b
14554220737af83ce09bc9955cf5659eab4f4de98c999bfb02a28c0608f09b4e07dfe0
144537cbac0d45d78547b09fb5a56e65770c68ce5112e648c9d2350c7c80fbdc2eb7ce
1435221e76b52cd13890935c1918437a9bf508c10d1ac1f936a25a338659824d11e9eb
14251680391ea31eb3546589ed9c6e78d1a78efb2a3bddd0eae4ba6b6c9a4353f4f44b
141515df323aad2b192d395ade8d304389e7bdc0af1a6233d9b8ab4e57ad42c15e5c13
140514f9ba75d9da9f43887116258817f14d2e37bef979e0bdcc11a820c160762ee801

Tutte le radici, dalla più recente: GET /v1/log/roots.

La chiave del nostro registro

ECDSA P-256 con SHA-256. ID della chiave 3b51f0f999b77a04bd96b2b86fa783237f5f33f29c55275a7e5a06ad7230829e, lo SHA-256 della chiave qui sotto in formato DER. Firma solo tree head, e la sua chiave privata non lascia mai AWS KMS.

PEM
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE42CpuoaS4/rNCAyQ08euvOtCa9X3
Zuq7bXjiCyeh4C0O92Ey6CbvOtfkS11IoLLFWFzzXrcpi/0L2vDeXsufyw==
-----END PUBLIC KEY-----
Le nostre marche temporali provengono dal nostro server RFC 3161, quindi ognuna di esse è registrata qui. L’ora contenuta in una marca temporale e l’ora in cui la sua voce è stata registrata stanno una accanto all’altra, e una volta che una radice le copre, nessuna delle due può cambiare.