Publiczne narzędzie „zero-trust". Wklej pakiet dowodowy (JSON) wygenerowany przez API ipIII, a przeglądarka policzy SHA-256 jego kanonicznego payloadu — lokalnie, w Twojej przeglądarce (Web Crypto crypto.subtle.digest) — i porówna z zadeklarowanym package_sha256. Żadne dane nie opuszczają Twojego urządzenia. Zero zewnętrznych bibliotek.
package_sha256 = wewnętrzny hash integralności). Nie potwierdza tożsamości wystawcy ani ważności
prawnej. Kryptograficzny podpis wystawcy (PAdES / znacznik czasu TSA / PQC) pozostaje
ROADMAP. Dopóki go nie ma, zgodny hash dowodzi spójności treści — nie jej pochodzenia.
Pakiet z GET /api/ip3/v1/reports/evidence-package/:id (oraz /engagements/:id/report-package)
zawiera pole package_sha256. API liczy je jako skrót kanonicznego payloadu (JCS / RFC 8785)
z wykluczeniem pól metadanych i doklejanych po hashu (generated_at, package_sha256, hash_scope, audit_chain, signature, tsa_stamp).
Ten weryfikator odtwarza dokładnie tę samą kanonikalizację JCS i te same wykluczenia po stronie klienta —
dlatego przelicza identyczny skrót niezależnie od kolejności kluczy w JSON.
package_sha256 (mechanizm kanoniczny)API buduje obiekt payload, a następnie dopisuje skrót jako ostatnie pole:
// strona serwera (Node.js, kanon — routes/ip3-canonical.js) const EXCL = ['generated_at','package_sha256','hash_scope','audit_chain','signature','tsa_stamp']; payload.package_sha256 = sha256( jcsCanonicalize(payload_bez_EXCL) ); // JCS/RFC8785, nie JSON.stringify // audit_chain, signature, tsa_stamp doklejane PO obliczeniu hasha (dlatego wykluczone)
Weryfikator odtwarza to samo: parsuje JSON, usuwa pola z listy EXCL, kanonikalizuje
tym samym algorytmem JCS/RFC 8785 (rekurencyjne sortowanie kluczy, bez białych znaków) i liczy
SHA-256 — porównuje z hashem zadeklarowanym. Zgodność potwierdzona na realnym pakiecie.
// strona klienta (przeglądarka, Web Crypto — CSP-safe)
const buf = new TextEncoder().encode(JSON.stringify(objBezPola));
const dig = await crypto.subtle.digest('SHA-256', buf);
const hex = [...new Uint8Array(dig)].map(b => b.toString(16).padStart(2,'0')).join('');
package_sha256
jest skrótem konkretnej serializacji, nie abstrakcyjnej treści. Weryfikuj pakiet dokładnie tak, jak zwrócił go
/api/ip3/v1.
| Werdykt | Znaczenie | Czego nie oznacza |
|---|---|---|
| ZGODNY | Policzony skrót = zadeklarowany package_sha256. Treść pakietu jest spójna z jego skrótem integralności. | Nie dowodzi, kto wystawił pakiet, ani jego ważności prawnej (brak podpisu wystawcy — ROADMAP). |
| NIEZGODNY | Skróty się różnią. Treść została zmieniona względem hasha, albo zmieniono kolejność/format serializacji. | Sam w sobie nie przesądza o złej intencji — może wynikać z re-formatowania JSON (patrz NOTE). |
| BŁĄD WEJŚCIA | JSON nie parsuje się, brak pola package_sha256 i nie podano oczekiwanego, albo hash ma zły format. | Nie jest werdyktem o pakiecie — to sygnał, że nie ma czego porównać. |
| Status | Znaczenie | Warunek nadania |
|---|---|---|
| LIVE | Weryfikator działa produkcyjnie na kliencie (Web Crypto). | Kod inline + brak zależności + reprodukcja kanonicznego skrótu API. |
| ROADMAP | Podpis wystawcy: PAdES / TSA / PQC. | Autentyczność (kto wystawił) — jeszcze nie zaimplementowana. |
| GAP | Uznanie hasha za dowód pochodzenia. | Zabronione — hash to integralność, nie tożsamość. |