NemId og Digital Signatur. Mere end blot et laksegl?

NemId er hot i øjeblikket, Nets er nemlig til salg. Salget har nogle konsekvenser, som kan være svære at diskutere, derfor vil jeg gerne prøve at bidrage til debatten med dette indlæg, ved at dykke lidt ned i, hvad en digital signatur egentlig er for en størrelse. Selv begynder jeg tit i ordbøger, når jeg skal i gang med noget nyt, da jeg synes etymologi er spændende. Det giver mig også en god forståelse for, hvad det er jeg har med at gøre. Derfor vil jeg også begynde med, at diskutere betydningen af begrebet “digital signatur”.

Ifølge etymonline.com stammer ordet “signatur” fra latin, nærmere bestemt fra ordet “signatura”, der skulle betyde “mønsteret fra et segl”. Dette er ganske interessant. En signatur er altså et mærke, oprindeligt “mønsteret fra et segl”. Det kender vi f.eks. fra lakseglet, hvor et brev blev lukket med varm lak og i den varme lak, blev trykket en signet, der afgav et mærke, som kunne identificere afsender. Udover at identificere afsender, kunne modtager også se om brevet havde været åbnet inden modtagelse, idet seglet da ville være brudt. Bestod et brev eller dokument af flere ark papir, ville disse blive hullet og bundet sammen med en segltråd som også ville gå igennem seglet. Signetten var noget personligt, som afsender skulle passe godt på. Med tiden blev der udviklet metoder, hvor breve kunne åbnes enten uden at skade seglet eller ved at lave en falsk signet fra seglet og bruge dette til at lave en ny forsegling af brevet. En falsk signet ville også kunne bruges til at sende falske breve og lave falske officielle dokumenter. Dette er ikke langt fra hvordan en digital signatur fungerer, men først lidt mere etymologi.

Slår man “signatur” op på ordnet.dk, henvises til ordet underskrift, og underskrift er forklaret med følgende to betydninger:

1. en persons navn skrevet med vedkommendes egen karakteristiske håndskrift som en slags identifikation, fx som bekræftelse på en aftale eller som afslutning i et brev
1.a det at skrive sit navn i et dokument, brev el.lign. og dermed fx indgå en aftale eller påtage sig et ansvar for indholdet

Underskrifter kender vi fra vores hverdag, hvor vi skriver under på lånedokumenter, ansættelsekontrakter og en sjælden gang et postkort eller et brev. Der står dog også følgende

elektronisk underskrift

kodning af elektroniske data der sikrer at modtageren af fx et e-brev ved hvem afsenderen er, at indholdet ikke er ændret, og at afsenderen ikke senere kan nægte at have sendt meddelelsen bruges fx ved handel på internettet

Og nu er vi ved berettigelsen af denne etymologiske rundtur: En elektronisk underskrift skal tjene det samme formål som tidligere tiders laksegl, nemlig at

  1. identificere afsender
  2. sikre at indholdet af dokumentet ikke er blevet ændret, efter signaturen er lavet.

Lighederne mellem en digital signatur og et laksegl er altså så slående, at man kan argumentere for, at at en digital signatur blot er en implementation af et laksegl. Men først lidt tekniske eksempler. Hvis man ikke har interesse i det tekniske, kan man springe til opsummeringen, men jeg håber dog, at man i det mindste skimmer eksemplerne.

Et eksempel
Hvis vi nu antager at jeg vil sende en mail til min kollega Frank, hvor jeg fortæller, at jeg vil give en øl i fredagsbaren. I dette tilfælde er det vigtig, at Frank kan se at det faktisk er mig, der har afsendt mailen, ellers vil han ikke tro på, at det er mig, der har sendt den. Dette skyldes muligvis, at jeg er en smule påholdende. Det er også vigtigt, at en eller anden sysadm ikke får opsnappet mailen og ændret beskeden til, at jeg vil give omgang til afdelingen. Sjovt nok er det lettere at få en flok af mennesker til at tro på gratis øl. Havde beskeden været sendt på papir, havde jeg kunne folde papiret sammen og lukke det med et segl. Frank ville nu kunne se, at jeg var afsender og at beskeden ikke havde været fiflet med undervejs. Begge dele kan også sikres med emailen.

Selgtråden
Først skal der væves en selgtråd ind i mailen. En mail er, i sin simpleste form, opbygget af nogle header-elementer, så en tom line, derefter beskeden efterfulgt af en linie med et punktum.

From: "Andreas" <andreas@example.org>
To: "Frank" <frank@example.org>
Date: Wen, 29 January 2014 16:02:43 +0100
Subject: Test message

Hej Frank
Jeg giver en (1) øl i fredagsbaren.
/Andreas
.

For at lave en segltråd for mailen, beregnes en checksum for mailen, f.eks. ved at anvende algoritmen SHA-256.

#!/usr/bin/env ruby

require 'openssl'
require 'base64'

sha265 = OpenSSL::Digest::SHA256.new

email = 'From: "Andreas" <andreas@example.org>
To: "Frank" <frank@example.org>
Date: Wen, 29 January 2014 16:02:43 +0100
Subject: Test message

Hej Frank
Jeg giver en (1) øl i fredagsbaren.
/Andreas
.'

puts Base64.encode64 sha265.digest(email)

Programstumpen udskriver checksummen som følgende sekvens af tegn:

fCTbkvXpYVmj8yJx3uWItnZ8EGqTmrvD4z5CIr30GRA=

Denne checksum kan så medsendes i mailen, f.eks. ved at tilføje en ekstra header:

X-CHECKSUM: v=fCTbkvXpYVmj8yJx3uWItnZ8EGqTmrvD4z5CIr30GRA= a=SHA-256 e=base64 b=[from, to, date, subject, body]
From: "Andreas" <andreas@example.org>
To: "Frank" <frank@example.org>
Date: Wen, 29 January 2014 16:02:43 +0100
Subject: Test message

Hej Frank
Jeg giver en (1) øl i fredagsbaren.
/Andreas
.

Frank kan nu i mailen se, at checksummen v er beregnet med SHA-256, encoded i base64 og er baseret på felterne ‘from’, ‘to’, ‘date’, ’subject’ og ‘body’.
Hvis emailen ændres, vil checksummen for den også ændres, så Frank kan selv beregne en checksum for den modtagne mail og sammenligne den med den oprindelige checksum og derved se, om mailen er blevet ændret undervejs.

Men da checksummen blot er en del af mailen, kan denne let ændres til at passe til en ændret mail, så dette er kun en del af løsningen. Chekcsummen skal have et laksegl, så man dels kan se om den er ændret og dels kan se at det er mig der har beregnet den. Der skal altså bruges en signet, et hemmeligt stempel som kun jeg kan sætte på chekcsummen.

Signetten og seglet
En signet kan findes i asymmetrisk kryptering. Asymmetrisk er kendetegnet ved, at der krypteres med en offentlig kendt nøgle og dekrypteres med en anden, hemmeligholdt nøgle, som regel kaldet den private nøgle. Det er dog også muligt at kryptere med den hemmelige nøgle og dekryptere med den offentlige nøgle.

Følgende programstump krypterer teksten “Hello World” med den private nøgle for derefter at dekryptere resultatet med den offentlige nøgle, hvorefter det sammenligner dette resultat med den oprindelige tekst og skriver “Dokument OK.”, hvis det er det samme:

#!/usr/bin/env ruby

require 'openssl'
require 'base64'

private_key = OpenSSL::PKey::RSA.new 1024
public_key = private_key.public_key

# Tekst som skal krypteres
document = 'Hello World'

# Krypter dokument med privat nøgle
encrypteddoc = private_key.private_encrypt(document)

# Dekrypter det kryptede dokument med ofentlig nøgle
decrypteddoc = public_key.public_decrypt(encrypteddoc)

#Check om resulatet er det samme som udgangspunktet
if decrypteddoc == document
	puts "Dokument OK."
end

Programmet udskriver følgende:

Dokument OK.

Det virker altså som forventet.

Det jeg krypterer med min private nøgle, kan jeg gå ud fra, kun kan dekrypteres med min offentlige nøgle. Dette er med til at identificere mig. Det eneste forudsætning er, at der findes et offentlig nøgle-lager, hvor man kan hente min offentlige nøgle.

Det betyder, at hvis jeg vælger at kryptere min checksum med den private nøgle, kan modtager bruge min offentlige nøgle til at dekryptere checksummen, for derefter at sammenligne den, med den som modtageren selv beregner for emailen. Hvis den passer, kan modtager konkludere: emailen er afsendt af en som kender den private nøgle og indholdet er ikke blevet ændret undervejs.

Det gør følgende kodestump:

#!/usr/bin/env ruby

require 'openssl'
require 'base64'

private_key =  OpenSSL::PKey::RSA.new 1024
public_key =  private_key.public_key

# Emailen der skal signeres
email = 'From: "Andreas" <andreas@example.org>
To: "Frank" <frank@example.org>
Date: Wen, 29 January 2014 16:02:43 +0100
Subject: Test message

Hej Frank
Jeg giver en (1) øl i fredagsbaren.
/Andreas
.'

# SHA-256 checksum beregneren
sha256 = OpenSSL::Digest::SHA256.new

#beregn checksum
checksum = sha256.digest(email)

#krypter med den private nøgle
crypted_checksum = private_key.private_encrypt(checksum)

# Base64 encode den, så den består af tegne der kan sendes som tekst
encoded_checksum = Base64.encode64(crypted_checksum)

# Udskriv den krypterede checksum
puts "Encoded checksum: " + encoded_checksum

Resultat

dEKcvKlRC4IO+e82ZM5C2lO31pAtJa+fBw8BD9HBaKwgMj/OhtcTtYwTFjoH
ijvtcEbbJxlp6qamuhgDYtr0qoR7l7fg4PUJsNNN70j2hXgufh0pqk5Udt8N
7g8jCE8CVjLvT+jx/Qq0F1RqOzNni0CCQl1k9axvyeBsovAw/g0DZ8eA78ww
DOholnNtysuQ+qWjlz81ohdUIl1bIKXI4DId1HGDsM3jxFqr+86HA2qbP/CY
DMvwzKZHSqB0e7kbgdkiUuoYHnnmRPyvZPODXuh5VMtby01eOcm/J8xP/J1H
66V/5rwFXzzWsFk1PW0scdPhxXTo0XBX/PGQTZkCNg==

Checksummen fungerer nu som segltråd og ved at kryptere checksummen med min hemmelige nøgle, har jeg plantet min signet i den varme lak. Resultatet svarer fuldstændig til et gammeldags laksegl. Tilbage er nu, at tilføje signaturen til emailen. Vi skifter værdien af v ud med den beregnede signatur og tilføjer information om, at checksummen er krypteret med RSA algoritmen.

X-SIGNATURE: v=dEKcvKlRC4IO+e82ZM5C2lO31pAtJa+fBw8BD9HBaKwgMj/OhtcTtYwTFjoHijvtcEbbJxlp6qamuhgDYtr0qoR7l7fg4PUJsNNN70j2hXgufh0pqk5Udt8N7g8jCE8CVjLvT+jx/Qq0F1RqOzNni0CCQl1k9axvyeBsovAw/g0DZ8eA78wwDOholnNtysuQ+qWjlz81ohdUIl1bIKXI4DId1HGDsM3jxFqr+86HA2qbP/CYDMvwzKZHSqB0e7kbgdkiUuoYHnnmRPyvZPODXuh5VMtby01eOcm/J8xP/J1H66V/5rwFXzzWsFk1PW0scdPhxXTo0XBX/PGQTZkCNg== a=SHA-256 e=base64 b=[from, to, date, subject, body] c=RSA
From: "Andreas" <andreas@example.org>
To: "Frank" <frank@example.org>
Date: Wen, 29 January 2014 16:02:43 +0100
Subject: Test message

Hej Frank
Jeg giver en (1) øl i fredagsbaren.
/Andreas
.

Igen forudsat at Frank kender min offentlige nøgle, kan han nu sikre sig, at emailen faktisk er sendt af mig og at den ikke er blevet ændret siden jeg afsendte den. Det kan han gøre med følgende smule kode:

#!/usr/bin/env ruby

require 'openssl'
require 'base64'

email = 'From: "Andreas" <andreas@example.org>
To: "Frank" <frank@example.org>
Date: Wen, 29 January 2014 16:02:43 +0100
Subject: Test message

Hej Frank
Jeg giver en (1) øl i fredagsbaren.
/Andreas
.'

# Min offentlig nøgle indlæses
public_key = OpenSSL::PKey::RSA.new '-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA42tvu0wXe0F/tlX8ykPl
RzcpDCk9BwmWuUGIAht1SJqdWM5CMLWzJ99mGJf2rfht7yiLHiQWOCnl85QZhTAc
U4QeDlMMusCesyRPQHELtLucaqMnubIo0EtFbZZtwF8g/QaKWPe3nuPKWYK8R14r
JwvSjmSbWOdzEFKr58RIsWIG4guw6aWCRg8QJR+xn4CH0lQeE462qUpcQAx16sEc
WXdlhxnIuiqajER4CdJnINpuljclBDwOg3lbiL04A4t6ASQqKT4Xw20NbdYk2P2u
NQw4BMYhH7u8+XSnZ/LEMVZTFtOhdvNAMhd7/2Yr8DITVN57WXoLzHkJPbEKEYvx
UwIDAQAB
-----END PUBLIC KEY-----'

# Modtageren gør det baglæns
sha256 = OpenSSL::Digest::SHA256.new
encoded_checksum = 'dEKcvKlRC4IO+e82ZM5C2lO31pAtJa+fBw8BD9HBaKwgMj/OhtcTtYwTFjoHijvtcEbbJxlp6qamuhgDYtr0qoR7l7fg4PUJsNNN70j2hXgufh0pqk5Udt8N7g8jCE8CVjLvT+jx/Qq0F1RqOzNni0CCQl1k9axvyeBsovAw/g0DZ8eA78wwDOholnNtysuQ+qWjlz81ohdUIl1bIKXI4DId1HGDsM3jxFqr+86HA2qbP/CYDMvwzKZHSqB0e7kbgdkiUuoYHnnmRPyvZPODXuh5VMtby01eOcm/J8xP/J1H66V/5rwFXzzWsFk1PW0scdPhxXTo0XBX/PGQTZkCNg=='
decoded_checksum = Base64.decode64(encoded_checksum)
decrypted_checksum = public_key.public_decrypt(decoded_checksum)
if(decrypted_checksum == sha256.digest(email))
	puts "Checksum matches"
end

Og resultatet af dette er heldigvis:

Checksum matches

Opsummering
En digital signatur består altså af følgende elementer:

  • En segltråd, bestående af en checksum
  • En signet, bestående af den hemmelige nøgle i asymmetrisk kryptering
  • Et segl, bestående af checksummen krypteret med den hemmelige nøgle

Svagheder
Kryptering kan brydes, om ikke andet, så med brute force. Sikkerheden i kryptering er ikke, at krypteringen er ubrydelig, men at krypteringen først kan brydes, når indholdet af det krypterede ikke længere er relevant. Budskabet “Vi angriber ved daggry” behøver derfor ikke stærkere kryptering, end at krypteringen først kan brydes ved middagstid i morgen.

Problemet er, at det er svært at afgøre hvor længe en kryptering kan holde. Dels afhænger det af, hvordan den teknologiske udvikling er, for med hurtigere computere, vil det tage kortere tid, at bryde krypteringen med brute force. Men det afhænger og dels af, at der ikke findes fejl i krypteringsalgoritmerne.

Det betyder, at en digital signatur der dannes i dag, ikke nødvendigvis har en særlig lang holdbarhed. Hvis der er en fejl, kan man potentielt allerede i morgen forfalske signaturen. Det har konskevenser for gyldigheden af signaturen. Hvis man i dag underskriver et lånedokument på et lån med 30 års løbetid, kan ende i en situation, hvor signaturen kan forfalskes allerede om 5 år. Hvad gør man så? Skal man underskrive dokumenterne en gang om året, så man kan opdatere signaturen til at benytte de nyeste algoritmer? Hvor mange dokumenter drejer det sig om for en gennemsnitlig borger?

Hvad har vi så?
En digital signatur, er altså ikke meget mere, end en softwareimplementation af et gammeldags laksegl. Sikkerheden består af to ting: den private nøgle er hemmeligholdt og at nøglen ikke kan forfalskes. Det, at nøglen ikke kan forfalskes, kan, nøjagtigt som med lakselget, være svært at garantere. Som jeg har nævnt tidligere, opdages der fejl i krypteringsalgoritmer og efterhåndens som computere bliver hurtigere, kan det blive muligt at brute force en forfalskning. Hemmeligholdelsen er straks lettere. Man kan f.eks. opbevare sin hemmelige nøgle på en krypteret USB-nøgle og passe godt på USB-nøglen. Det at “passe godt på” sin private nøgle, kræver dog, at man har sikkerhed for, at krypteringsnøglen ikke forlader den maskine man bruger til at underskrive på. Personligt ville jeg foretrække en open source løsning, hvor jeg ved selvsyn, kan sikre mig, at programmet som danner en signatur, ikke kopierer eller distribuerer min nøgle til andre. Dette kræver også, at underskriften sker på min maskine. Min hemmelige nøgle skal forblive hemmelig.

Lad mig lige opsummere:

  • Den hemmelige nøgle skal forblive hemmelig
  • Den hemmelige nøgle skal forblive i min varetægt, også under brug
  • En digital underskrift har en begrænset gyldighedsperiode
  • Man kan ikke på forhånd afgøre, hvor længe en digital underskrift er gyldig

Problemet NemId
Med NemId mødes ingen af de førnævnte krav. Jeg har ikke selv adgang til min private nøgle. Jeg har ingen garanti for at den forbliver hemmelig og det virker som om, at det bliver fuldstændigt ignoreret, at en digital underskrift har begrænset varighed. Udover disse problemstillinger, der begrænser NemIds reelle værdi som lagtidsholdbar, juridisk gyldig underskrift, er der også nogle andre, mere samfundmæssige problemer.

Det største problem med at anvende NemId som digital signatur er, at jeg ikke selv er i besiddelse af den nøgle – min signet, som bruges til at underskrive dokumentet. Når jeg skal underskrive et dokument med min digitale signatur, skal jeg bede en privatejet virksomhed om, at undskrive på mine vegne. Det vil sige, at jeg i princippet er umyndiggjort og ejerne af firmaet bag NemId er mine værger.

Derudover kan jeg kun kan anmode om at Nets underskriver og jeg kan ikke det modsatte. Der er ingen måde, hvorpå jeg kan sikre eller forhindre, at Nets underskriver dokumenter på mine vegne. Der er heller ingen måde hvorpå, jeg kan bevise, at jeg ikke selv har underskrevet et dokument.

Jeg er altså under komplet administration af en privatejet virksomhed.

En virksomhed som er til salg.

Share Button
The following two tabs change content below.
Profile photo of Andreas Ryge
Med en baggrund i datalogi og psykologi, er jeg humanisten i datalogi. Arbejdsmæssigt har jeg været lidt omkring. Har været selvstændig, lavet systemer til skattemyndigheder i det meste af verden, arbejdet med musikbranchen, lavet systemer til telebranchen og er idag endt i AudienceProject. Gennem tiden har jeg prøvet en del roller, blandt andet projektleder, scrum master, afdelingsleder og arbejder i øjeblikket som Data Scientist - en lidt anden rolle, end den typiske udvikler-rolle. Har også været en del omkring i sprog og teknologier, bla C/C++, Tcl, Prolog, Java, Perl, Python, Ruby, Clojure og arbejder idag mest med Scala. Mine interesser mange, særligt machine learning, distribuerede systemer og sikkerhed. Og så interesserer jeg mig også lidt for filosofi. Forvent at skriblerierne stritter i alle retninger.

Flattr this!

3 kommentarer for “NemId og Digital Signatur. Mere end blot et laksegl?

  1. Frank Vilhelmsen
    25. februar 2014 at 09:43

    Virkelig god artikel på nær det faktum at jeg aldrig har modtaget den omtalte øl. Som tidligere aktiv deltager på tinglysnings projektet kommer jeg til at tænke på Jyske lov og det koncept med at stole på. At modtage et skøde betyder at man ejer en grund, et hus eller måske er man på vej i fængsel. Før 1551 fik man overdraget “retten” til et stykke jord ved, “på tinge kastede sælger jord fra den solgte ejendom i købers skød. Heraf kommer benævnelsen ”skøde”. De øvrige tilstedeværende på tinge som overværede handlingen kunne bekræfte at overdragelsen var sket.

    Sådan er det ikke længere.. Alligevel virker det som vi stadig har den mentale model “at stole på” i forskellige niveauer af disse sikkerheds løsninger. I mit stille sind ulmer en anden ide om sikkerhed og jeg håber på at mange andre kan tænke nye retninger der frigøre os fra tredieparts håndtering og rå maskinkraft.

  2. Eva Petersen
    7. oktober 2016 at 11:28

    Når man har været en tur på Post- og Telegrafmuseet og har hørt historierne om, hvordan der blev fiflet med segl, så er den ikke-problematiserende beskrivelse lidt morsom – er godt klar over, at det ikke er pointen 😉

    • Profile photo of Andreas Ryge
      7. oktober 2016 at 14:36

      Jeg håber jeg misforstår din kommentar, for jeg synes at jeg netop problematiserer laksegl og derved dets digitale modpart, NemId.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *