Maskinoversættelse, ikke gennemgået af en modersmålstalende. Engelsk er referencen.

Validering og evidensRedigér på GitHubKilde: docs/EVIDENCE-PACKS.md

Bevispakker: en signeret registrering af en GNSS-tillidshændelse

En pakke er en teknisk registrering, ikke en juridisk udtalelse. Den angiver, hvad Kshana-motoren beregnede ud fra en angivet modtagerlog under en angiven konfiguration, og lader enhver kontrollere, at intet i den er ændret bagefter. Den siger ikke, hvad der forårsagede en hændelse, hvem der var ansvarlig, om nogen forpligtelse blev nået, eller at loggen viser, hvad modtageren i virkeligheden modtog. Manifestet og oversigten siger begge dette.

En bevispakke er til en hændelsesrapport, en forsikringsgiver eller en myndigheds spørgsmål: »hvad sagde jeres system om GNSS-signalet mellem disse to tidspunkter, og kan vi stole på den registrering?«

Lav en pakke#

# once: a signing key. The private key stays with you; never commit it.
kshana evidence keygen --out signer.key        # writes signer.key (0600) and signer.key.pub

kshana receiver-trust evidence session.toml \
    --from 100 --to 260 \                       # seconds since the first epoch, or ISO-8601 UTC
    --key signer.key --out pack/ \
    --title "Berth 4, 14 June"                  # optional

For en pakke lavet ud fra en laboratoriesession registrerer --lab-attestation lab.toml operatørens erklæring om opstillingen (ledningsbåret eller afskærmet, dæmpning eller kabinet, hvad der udsendte eventuel RF) i det signerede manifest; se HARDWARE-SAFETY.md. Den registreres, som den er givet, og verificeres aldrig.

--from og --to er sekunder siden logens første epoke eller et UTC-tidspunkt i ISO-8601, når loggen angiver sin egen starttid. --out må ikke allerede indeholde filer. --created-utc tager et rigtigt UTC-tidspunkt som 2026-01-02T03:04:05Z (alt andet afvises) eller none, som udelader oprettelsestidspunktet og gør pakken reproducerbar byte for byte. Oprettelsestidspunktet er det, underskriveren angiver; intet kontrollerer det mod et ur, og det er det, det valgfrie tidsstempelbevis er til.

Nøglefilen indeholder et Ed25519-seed på 32 byte som 64 hexcifre; angiv din egen (for eksempel en, der opbevares i dit nøglestyringssystem) eller lad keygen lave en. kshana advarer, hvis filen kan læses af andre brugere. .gitignore udelukker *.evidence-key; navngiv din nøgle sådan, hvis den ligger i et checkout.

Hvad der er i en pakke#

Strukturen i en bevispakke. En modtagerlog (NMEA, u-blox UBX, RINEX 3 eller en Android-log) og et tidsvindue går ind i kshana receiver-trust evidence, som skriver syv filer: log-slice.bin, config.json, epochs.json, summary.html, manifest.json, manifest.sig og en valgfri timestamp.tsr. Manifestet registrerer SHA-256 af hele loggen og af hver fil samt en hashkæde over filerne; signaturen dækker manifestet. kshana evidence verify kontrollerer signaturen, hver fils hash, kæden og at ingen fil uden for listen findes, og afslutter med 0, når det er verificeret, 1, når noget fejlede, og 3, når underskriveren ikke var fastlåst. En pakke er en teknisk registrering, ikke en juridisk udtalelse.Strukturen i en bevispakke. En modtagerlog (NMEA, u-blox UBX, RINEX 3 eller en Android-log) og et tidsvindue går ind i kshana receiver-trust evidence, som skriver syv filer: log-slice.bin, config.json, epochs.json, summary.html, manifest.json, manifest.sig og en valgfri timestamp.tsr. Manifestet registrerer SHA-256 af hele loggen og af hver fil samt en hashkæde over filerne; signaturen dækker manifestet. kshana evidence verify kontrollerer signaturen, hver fils hash, kæden og at ingen fil uden for listen findes, og afslutter med 0, når det er verificeret, 1, når noget fejlede, og 3, når underskriveren ikke var fastlåst. En pakke er en teknisk registrering, ikke en juridisk udtalelse.
Fil Indhold
log-slice.bin de rå bytes fra modtagerloggen for vinduet
config.json scenariet som kørt (hver monitortærskel, hændelse og sammenligningsregel), de monitorer, der kørte, kalibreringsbaselinen og scenariehashen; for et fartøj også den vejledende erklæring, som alt output for fartøjer bærer (vejledende software, ikke typegodkendt navigationsudstyr); fra 0,36 geometry_model (tabellen [geometry], som faktisk blev brugt, geometrimonitorens vægt, hver proveniens og klassereglerne). Mappenavne og indlejrede nyttelaster fjernes.
epochs.json hver epoke i vinduet med motorens statistik, alarmerne (årsagerne) og tillidstilstanden; fra 0,36 også dens satellit-geometry (god, forringet med årsager eller ukendt, hvor loggen ikke giver nogen satellitgeometri) og en class på hver slutning (geometry, environment, inconsistency)
summary.html en selvstændig oversigt uden scripts: identifikation, hashes, resultater, årsager, et geometrispor (epoker efter geometristatus) adskilt fra klasserne af slutninger (0,36), hver tærskel, tabellen pr. epoke og registreringens begrænsninger
manifest.json motorversion, vindue, oprettelsestidspunkt, logens format og navn, SHA-256 af hele loggen, udsnittets interval og SHA-256, underskriverens offentlige nøgle og fingeraftryk, hver fils størrelse og SHA-256 og en hashkæde over filerne
manifest.sig Ed25519-signatur over de nøjagtige bytes i manifest.json
timestamp.tsr valgfrit RFC 3161-tidsstempelbevis

Logudsnit. Læseren rapporterer kildebyteintervallet for hver epoke, så udsnittet er det mindste byteinterval, der rummer hver epoke i vinduet (byte-range): NMEA, u-blox UBX, RINEX 3-observationer og Android-logs. Det hashes som rå bytes, aldrig som afkodet tekst. For en live-strøm eller RINEX 2 findes der intet interval; hele loggen medfølger da, og manifestet siger whole-log (vinduet begrænser, hvilke epoker der rapporteres, ikke hvilke bytes der medtages). Oversigten angiver, hvilket der gælder. Et udsnit er en registrering af vinduets bytes, ikke en selvstændig log: for eksempel har et RINEX-udsnit ingen filheader.

Hashkæde. Manifestet oplister filerne i en fast rækkefølge. link₀ = SHA-256("kshana- evidence-chain/1"); for hver fil linkᵢ = SHA-256(linkᵢ₋₁ ‖ SHA-256(file) ‖ len(name) ‖ name) (længde som 4 bytes, big-endian). Det sidste led er chain_head. At omordne, fjerne eller udskifte en fil ændrer kæden; signaturen dækker kæden.

Verificér en pakke#

kshana evidence verify pack/ --pubkey signer.key.pub [--log session.nmea] \
    [--require-timestamp] [--allow-unpinned] [--json]

Afslutningsstatus 0 betyder verificeret; 1 betyder, at noget fejlede; 2 betyder en brugsfejl; 3 betyder, at pakken er intakt, men at dens underskriver ikke var fastlåst (se nedenfor). Hver kontrol rapporterer bestået, fejlet eller sprunget over, og hver fejl navngives:

Fejlkode Betydning
manifest-missing, manifest-malformed, unsupported-format manifestet kan ikke læses
signature-missing, signature-malformed, signature-invalid ingen signatur, ikke en hexsignatur på 64 byte med små bogstaver, eller den kan ikke verificeres over manifest.json
public-key-malformed, public-key-mismatch nøglen er ugyldig eller afviger fra den, du angav
file-missing, file-size-mismatch, file-hash-mismatch en opført fil mangler eller afviger fra manifestet; filen navngives
unlisted-file en fil er i pakken, men ikke i manifestet
chain-mismatch, chain-head-mismatch et led er ikke det, dets input giver; filen navngives
artifact-list-malformed, slice-record-inconsistent, epoch-count-mismatch manifestet modsiger sig selv eller epochs.json
full-log-hash-mismatch, slice-not-from-full-log med --log: den log, du har, er ikke den registrerede, eller udsnittet er ikke det interval af den
timestamp-missing, timestamp-malformed, timestamp-imprint-mismatch se nedenfor

At ændre ét byte i en hvilken som helst fil får verifikationen til at fejle med den tilsvarende årsag: en ændret artefakt rapporteres som den fils hash-mismatch og intet andet; et ændret manifest får signaturen til at fejle. At genberegne hashes og kæden efter redigering af en fil hjælper ikke uden signeringsnøglen; kun signaturen fejler da.

Fastlås nøglen. Uden --pubkey beviser en pakke kun, at den er intakt i forhold til den nøgle, den selv navngiver, og som enhver kan generere. Verifikationen afslutter derfor med 3 og siger »INTACT, BUT THE SIGNER IS NOT PINNED« i stedet for »VERIFIED«; --allow-unpinned accepterer pakkens egen nøgle med vidende og udskriver »VERIFIED against the key the pack names itself (signer NOT pinned; pass --pubkey)«. Få underskriverens offentlige nøgle fra underskriveren ad en vej, du stoler på (ikke fra pakken), og angiv den med --pubkey: 64 hexcifre eller filen .pub. Hvis den private nøgle angives ved en fejl, genkendes det og afvises. Fingeraftrykket (de første 128 bit af nøglens SHA-256, 32 hexcifre) udskrives, så det kan sammenlignes med øjet; at fastlåse hele nøglen er den pålidelige vej.

Pakkeformat og verifikationsprocedure (normativ)#

Dette afsnit er den specifikation, en uafhængig verifikator skrives ud fra. Ord med store bogstaver er krav. En pakke er en mappe (eller et hvilket som helst kort fra filnavn til bytes) med filer, der hedder præcis som nedenfor; en verifikator arbejder på bytes i hver fil, som den er gemt, og serialiserer aldrig noget igen.

Filer. Artefaktfilerne er i denne faste rækkefølge log-slice.bin, config.json, epochs.json, summary.html. En pakke har også manifest.json og manifest.sig og KAN have timestamp.tsr. Ethvert andet navn er en fil uden for listen.

Hex. Hver hexstreng består kun af små bogstaver og 0-9a-f, uden blanktegn; store bogstaver accepteres ikke. SHA-256-værdier er 64 cifre, den offentlige nøgle er 64 cifre, signaturen er 128 cifre.

manifest.sig. Hex med små bogstaver og 128 cifre for Ed25519-signaturen på 64 byte (RFC 8032, den rene Ed25519-ordning) over de nøjagtige bytes i manifest.json, efterfulgt af præcis ét \n og intet andet. Signaturen SKAL kontrolleres strengt: en signatur, hvis S-værdi ikke er mindre end gruppens orden L, er ugyldig.

manifest.json. Et UTF-8 JSON-objekt. Dets medlemmer (en verifikator SKAL finde hvert med den angivne JSON-type; yderligere medlemmer ignoreres):

medlem type betydning
format streng SKAL være lig med kshana-evidence/1
title, engine_version, disclaimer streng beskrivende
created_utc streng eller null oprettelsestidspunkt, beskrivende
window objekt {from_s, to_s} tal, sekunder
epochs_in_window ikke-negativt heltal antallet af poster i JSON-arrayet i epochs.json
log objekt format streng, file_name streng, full_sha256 hex, full_bytes ikke-negativt heltal, start_label streng eller null og slice
log.slice objekt kind (præcis byte-range eller whole-log; enhver anden værdi gør manifestet misdannet), start og end ikke-negative heltal (byteforskydninger, slut eksklusiv), sha256 hex
signer objekt algorithm streng (ed25519), public_key hex (32 bytes), fingerprint streng
artifacts array af objekter én pr. artefaktfil, i den faste rækkefølge: name streng, role streng, bytes ikke-negativt heltal, sha256 hex, link hex
chain_head hex det sidste led
lab_attestation objekt, valgfrit findes kun i en pakke lavet ud fra en laboratoriesession (--lab-attestation): operatørens erklæring operator, organisation, date, setup (conducted eller shielded), attenuation_db eller enclosure, emitter, statement og eventuelt signature, registreret som givet. Den dækkes af manifestets signatur og verificeres aldrig; en verifikator rapporterer den som »attested by the named operator; not verified by Kshana«. Fraværende ellers, og en pakke uden den er uændret

signer.fingerprint er de første 32 hexcifre af SHA-256 over de 32 bytes i den offentlige nøgle.

Hashkæde. link0 er SHA-256 af de 23 ASCII-bytes kshana-evidence-chain/1. For hver artefakt i rækkefølge, link = SHA-256( previous_link (32 bytes) ‖ SHA-256(file) (32 bytes) ‖ len(name) as 4 bytes big-endian ‖ name as UTF-8 ), hvor SHA-256(file) tages fra manifestets registrerede sha256 for den artefakt (så kæden er en egenskab ved manifestet og kontrolleres mod det, ikke mod filerne).

Procedure. En verifikator udfører disse trin i rækkefølge og samler hver fejl; resultatet er mængden af fejl, hver en code og, hvor det er angivet, filen name. Den MÅ IKKE standse ved den første fejl, undtagen hvor det er angivet. pin er den offentlige nøgle, verifikatoren fik besked om at stole på, hvis nogen.

  1. Intet manifest.json: fejl manifest-missing; stop.
  2. Hvis manifest.json ikke er et JSON-objekt med hvert medlem ovenfor i de angivne typer (herunder artifacts poster med hvert medlem og log.slice): fejl manifest-malformed. Ellers, hvis format ikke er værdien ovenfor: unsupported-format.
  3. Signaturfase. Denne fase udføres, uanset om manifestet kunne læses. Hvis manifestet kunne læses, er den navngivne nøgle signer.public_key; hvis den ikke er 64 hexcifre med små bogstaver, fejl public-key-malformed (ingen navngiven nøgle); ellers, hvis signer.fingerprint ikke er dens fingeraftryk, fejl public-key-malformed (nøglen forbliver brugbar). Hvis både en pin og en navngiven nøgle findes og er forskellige: fejl public-key-mismatch. Kontrolnøglen er pin, hvis en blev givet, ellers den navngivne nøgle, hvis der er en; med ingen af dem er der ingen kontrolnøgle (det gælder også alle tilfælde, hvor manifestet ikke kunne læses, og ingen pin blev givet). Hvis der ikke er nogen manifest.sig: signature-missing. Ellers, hvis filen ikke er præcis 128 hexcifre med små bogstaver plus ét \n: signature-malformed. Ellers, hvis der er en kontrolnøgle, som ikke er en gyldig Ed25519-offentlig-nøgle-kodning: public-key-malformed. Ellers, hvis der er en kontrolnøgle, og signaturen ikke kan verificeres strengt over bytes i manifest.json (uanset hvad de er): signature-invalid. (Uden kontrolnøgle kontrolleres signaturen ikke, og der rejses ingen fejl for det.)
  4. Hvis manifestet ikke kunne læses (trin 2 gav manifest-malformed): stop her.
  5. Artefakter. Hvis navnene i artifacts ikke præcis er de fire ovenfor i rækkefølge: artifact-list-malformed. Derefter for hver manifestpost i rækkefølge: hvis pakken ingen fil har med det navn, file-missing (navn); ellers, hvis dens længde afviger fra bytes, file-size-mismatch (navn); og uafhængigt heraf, hvis SHA-256 af filen afviger fra sha256, file-hash-mismatch (navn).
  6. Filer uden for listen: for hver fil i pakken udover manifest.json, manifest.sig, timestamp.tsr og navnene i manifestets artifacts: unlisted-file (navn).
  7. Kæde. Gå gennem manifestets artifacts i rækkefølge fra link0. Hvis en posts sha256 ikke er 64 hexcifre med små bogstaver: manifest-malformed, og kæden opgives (ingen kontrol af hovedet). Ellers beregnes leddet; hvis det afviger fra postens link: chain-mismatch (navn). Efter gennemgangen, hvis kæden ikke blev opgivet, og det sidste led afviger fra chain_head: chain-head-mismatch.
  8. Udsnit og epoker. Rejs slice-record-inconsistent (højst én gang pr. årsag, og en verifikator rapporterer koden én gang, uanset hvor mange årsager der gælder), hvis noget af følgende gælder: start > end; end > full_bytes; posten log-slice.bin har sha256, der afviger fra slice.sha256; den posts bytes afviger fra end - start; eller kind er whole-log, og et af start != 0, end != full_bytes, slice.sha256 != full_sha256 gælder. Hvis epochs.json findes og kan fortolkes som et JSON-array, hvis længde afviger fra epochs_in_window: epoch-count-mismatch.
  9. Hel log. Kun hvis verifikatoren fik de oprindelige logbytes: hvis deres SHA-256 afviger fra log.full_sha256, full-log-hash-mismatch; ellers, hvis intervallet start..end ikke ligger inde i loggen, eller logbytes dér afviger fra log-slice.bin, slice-not-from-full-log.
  10. Tidsstempel. Uden timestamp.tsr: hvis verifikatoren fik besked om at kræve et, timestamp-missing; ellers intet. Med et: hvis det ikke kan læses som et RFC 3161-bevis eller -svar (se nedenfor), timestamp-malformed; ellers, hvis dets meddelelsesaftryk ikke er hashen, i aftrykkets egen algoritme (SHA-256, SHA-384 eller SHA-512), af bytes i manifest.json: timestamp-imprint-mismatch.

Pakken er verificeret netop når mængden af fejl er tom. Om underskriveren var fastlåst, rapporteres separat og ændrer ikke mængden af fejl.

Tidsstempelbevis. Et bevis er en DER-ContentInfo, hvis indholdstype er CMS SignedData (1.2.840.113549.1.7.2), og hvis indkapslede indholdstype er id-ct-TSTInfo (1.2.840.113549.1.9.16.1.4); et svar er en DER-TimeStampResp (en PKIStatusInfo efterfulgt af beviset), hvis status er 0 eller 1. Meddelelsesaftrykkets algoritme i TSTInfo skal være SHA-256, SHA-384 eller SHA-512 med en digest af den algoritmes længde, og dens genTime et rigtigt UTC-kalendertidspunkt. BER med ubestemt længde accepteres ikke. Autoritetens signatur og certifikatkæde kontrolleres kun, når betroede ankre er givet (--tsa-ca, nedenfor).

Evidensetiketten (0,40)#

En pakke bygget af 0,40 eller senere bærer inde i config.json en post evidence (niveauet, VALIDATED, MODELLED eller PARTNER, som er den svageste status blandt dens rækker, og id'erne og kravene for de verifikationsmatrixrækker, pakkens indhold hviler på: rækken for pakkeintegritet, rækkerne for receiver-trust og rækkerne for jammertest-scoring eller rundtur for disse pakker) og config_version "1.1". Den ligger inde i config.json, så manifestets filhash, hashkæden og signaturen dækker den: at ændre den får verificeringen til at fejle. kshana evidence verify rapporterer niveauet og række-id'erne.

Ændringen er additiv og kun fremadrettet. Manifestets format forbliver kshana-evidence/1: den normative tekst ovenfor siger, at en verifikator SKAL finde den værdi, og clean-room-verifikatoren i scripts/ gør det. Den mindre version bæres derfor af config_version (fraværende i en pakke lavet før 0,40, hvilket betyder 1,0), ikke af en ny streng format. En pakke lavet før 0,40 har ingen etiket og verificeres uændret; kshana evidence verify siger "no evidence label (pre-0.40 pack)". Testene er tests/evidence_pack_label.rs (herunder de indlagte uafhængige pakker fra før 0.40) og tests/evidence_labels_doc_sync.rs.

RFC 3161-tidsstempel (valgfrit)#

Et tidsstempelbevis fra en tidsstemplingsautoritet viser, at manifestet fandtes på et tidspunkt, autoriteten bekræfter. Beviset er over manifest.json, så det rekvireres, efter pakken er lavet (der er ingen måde at levere et på, når pakken oprettes, og create_bundle afviser et bevis, der ikke er over netop det manifest):

openssl ts -query -data pack/manifest.json -sha256 -cert -out req.tsq
# send req.tsq to your authority, get the response, then:
kshana evidence attach-timestamp pack/ response.tsr
openssl ts -verify -in response.tsr -data pack/manifest.json -CAfile authority-ca.pem

kshana evidence verify læser beviset (et nøgent bevis eller et fuldt svar), kontrollerer, at det blev givet, og at dets meddelelsesaftryk svarer til hashen af manifest.json, og udskriver det tidspunkt, det angiver. Uden betroede ankre tilføjer den »timestamp authority signature not verified by Kshana« og rapporterer authority_signature_verified: false; kør linjen openssl ts -verify ovenfor for den del. Et bevis, hvis aftryk afviger, eller som ikke kan fortolkes, er en fejl. Bevisets indholdstyper, aftryks længde og genereringstidspunkt kontrolleres for rimelighed.

Med --tsa-ca authority-ca.pem (ét eller flere PEM-certifikater, alle betroede) kontrollerer verify også autoriteten, offline, på samme måde som openssl ts -verify: de signerede attributters meddelelsesdigest, signaturen (RSA PKCS#1 v1.5, RSA-PSS, ECDSA P-256 eller P-384), ESS-bindingen til signeringscertifikatet, underskriverens kritiske udvidede nøgleanvendelse timeStamping og kæden til et selvudstedt anker, hvor hvert certifikat er gyldigt ved beviset genTime. En fejl rapporteres som timestamp-authority-invalid med den første kontrol, der fejlede, og authority_signature_verified er kun true, når alt bestod. Tilbagekaldelse (CRL eller OCSP) kontrolleres ikke. Denne verifikator stemmer overens med OpenSSL 3.0.13 på 27 selvgenererede tilfælde (tests/fixtures/evidence_tsa/PREREGISTRATION.md).

Beviset ligger ved siden af det signerede manifest, ikke inde i det. Intet i signaturen eller kæden dækker det, så et bevis kan fjernes, eller et andet gyldigt bevis kan sættes ind, uden at signaturen fejler. verify noterer derfor, når en pakke ikke har noget, og --require-timestamp gør et manglende bevis til en fejl (timestamp-missing); et indsat bevis opdages kun, hvis det ikke passer til manifestet. attach-timestamp afviser at overskrive et eksisterende bevis, medmindre du angiver --replace. Hvis et tidsstempel betyder noget for dig, så opbevar beviset og verifikationsresultatet hos dine egne optegnelser, og kræv det.

Fra kode#

kshana::evidence::build_receiver_trust_pack er det ene indgangspunkt, som kommandolinjen og enhver anden flade kalder for at lave en pakke: et scenarie, logens bytes (og navigationsfilens, for RINEX), vinduet som tekst, en titel og et valgfrit oprettelsestidspunkt samt signeringsseedet ind; filerne, antallet af epoker, udsnittet, manifesthashen og underskriverens fingeraftryk ud. Den læser ingen filer og intet ur, så de samme input giver de samme bytes. Under den er create_bundle og verify_bundle rene funktioner: bytes ind (EvidenceInput, et seed på 32 byte, et BTreeMap<String, Vec<u8>> af filer), serialiserbare resultater ud (Files, VerifyReport). De bruger ingen filer, intet ur og ingen processtilstand og bygges til wasm32, så Python-, WebAssembly- og serverfladerne kalder dem uændret. Kommandolinjen er en tynd indpakning om dem.

Hvad en pakke ikke gør#

  • Den kører ikke vurderingen igen. Enhver med den fulde log og config.json kan køre kshana receiver-trust igen og sammenligne med epochs.json; pakken beviser, hvad der blev registreret, ikke at motoren havde ret.
  • Den beviser ikke, at loggen er ægte eller fuldstændig. Hashen af den fulde log binder registreringen til én fil; hvor den fil kom fra, er det operatørens sag at fastslå.
  • Den indeholder intet krav om ydeevne for detektion eller afvisning af interferens.
  • Den er en teknisk registrering og ikke en juridisk udtalelse eller en certificering.