Parašas, perskaičiuota maiša ir sąžiningas įspėjimas
Praėjusią pamoką išsiuntei dokumentą ir kiekvienam pasirašytojui nusiuntei nuorodą el. paštu. Ši pamoka įžiebia nuorodą: pasirašytojas atveria savo puslapį, peržiūri dokumentą ir pasirašo. Ir čia sutinki sąžiningą ribą, kas šis parašas yra.
Kas čia yra parašas. Trys dalykai, užfiksuojami pasirašytojo eilutėje pasirašymo akimirką:
signed_name— pilnas vardas, kurį įvedė,signed_at— serverio laiko žyma,signed_doc_hash— dokumento SHA-256 tą akimirką.
Ta trijulė ir yra visas parašas. Trečias laukas — laikantis svorį, o tai, kaip jis apskaičiuojamas, ir yra visa esmė.
Perskaičiuok maišą — niekada nepasitikėk saugoma. Kai pasirašytojas pasirašo, serveris neskaito documents.file_hash iš eilutės. Jis iš naujo atveria saugomus baitus ir maišuoja juos dabar:
integ, err := h.checkIntegrity(r.Context(), doc) // iš naujo maišuok saugomą failą šią akimirką
// ...
q.SignSigner(ctx, db.SignSignerParams{ /* SignedDocHash: &integ.CurrentHash */ })
Parašas liudija baitus, kurie iš tikrųjų egzistuoja pasirašymo metu. Jei failas būtų pakeistas po įkėlimo, perskaičiuota maiša skirtųsi nuo file_hash, juosta rėktų TAMPER DETECTED, o parašas sąžiningai užrašytų pakeistą maišą — ne tą, kurią teigia duomenų bazė. Pasitikėti saugoma maiša sugriautų visą mechanizmą: sertifikuotum skaičių, ne dokumentą.
Vienkartinis pasirašyti, daugkartinis peržiūrėti. Pasirašytojas turi galėti atverti nuorodą, perskaityti dokumentą, uždaryti, pagalvoti ir grįžti — tiek kartų, kiek nori. Bet niekada negali pasirašyti dukart. Abu išplaukia iš vienos sargybos užklausoje:
UPDATE signers SET status='signed', signed_name=$2, signed_at=now(), signed_doc_hash=$3
WHERE id = $1 AND status = 'pending'; -- pereina tik laukiantis pasirašytojas
:execrows grąžina, kiek eilučių pasikeitė. Pirmas pasirašymas perverčia pending → signed ir grąžina 1. Antras to paties žetono POST atitinka status='pending' — jau nebe tiesa — ir grąžina 0; valdiklis tiesiog parodo jau pasirašytą būseną. Peržiūra (GET) tokios sargybos neturi, tad veikia amžinai. Tas pats žetonas, du elgesiai, abu teisingi — užtikrinti WHERE, L9 pamoka ketvirtą kartą.
Paskutinis pasirašytojas užbaigia dokumentą. Po sėkmingo pasirašymo valdiklis suskaičiuoja likusius pending pasirašytojus. Jei nė vieno nebeliko, dokumentas perverčiamas sent → completed — toje pačioje transakcijoje kaip parašas, tad „pasirašyta" ir „užbaigta" niekada negali nesutapti.
Įspėjimas — pamoka, ne išnaša. Pasakyk aiškiai, kas tai yra:
Šis parašas — įvestas vardas, laiko žyma ir dokumento SHA-256 atspaudas pasirašymo metu. Tai daro jį atspariu klastojimo įrodymui — gali pasakyti, ar dokumentas vėliau pasikeitė — ir nieko daugiau. Tai nėra kvalifikuotas ar eIDAS elektroninis parašas ir nėra tapatybės įrodymas.
Ši programa daro įrodymą, ne prevenciją. Ji gali pasakyti, kad dokumentas pasikeitė; ji negali sustabdyti kažko jį keičiant ir neįrodo, kas pasirašė. Pasirašyti klastotą dokumentą net leidžiama — įspėjimas rodomas, o parašas sąžiningai užrašo maišą, kurią matė. Pateikti supaprastintą kriptografiją tarsi teisiškai kvalifikuotą pasirašymą būtų tikroji nesėkmė. Kitas žingsnis priverčia tave tai sukelti — įspėjimas, kurį pats įjungi, yra tas, kurį prisiminsi.
Ši pamoka:
- Pasirašytojo puslapis ir pasirašymo srautas — peržiūra, atsisiuntimas, pasirašymas — su vientisumu, perskaičiuojamu kiekvienoje peržiūroje.
- Vienkartinis pasirašymas, paskutinis-pasirašytojas-užbaigia taisyklė ir sąžiningumo įspėjimas kiekviename pasirašymo puslapyje.