Tullverket

Frågor och svar om PKI (autack och signering)

Vi svarar på de vanligaste frågorna kring vad som gäller för PKI, det vill säga autack och signering. Observera att vid skillnader mellan detta dokument och den tekniska specifikationen är det den tekniska specifikationen som gäller.

Checksumma

Vilken checksummealgoritm ska vi använda?

Använd checksummealgoritmen SHA-256.

På vilken del av EDIFACT-överföringen ska checksumman beräknas?

UNH till och med UNT.

Vilken kodning ska användas av den binära checksumman i autacken?

Checksumman ska representeras hexadecimalt (inte base-64-kodad) i autacken. Det ska inte vara några mellanslag i det hexadecimala värdet.

Hur beräknar vi checksumman?

Det beror på vilket utvecklingsplattform ni använder, men det kan se ut ungefär enligt nedan:

byte [] unhTillUnt = ....
md = MessageDigest.getInstance("SHA-256");
md.update(unhToUnt, 0, unhTillUnt.length);
byte [] checksum = md.digest();

Finns det några kommandoradsverktyg för att beräkna en checksumma?

OpenSSL kan användas.

openssl dgst -sha256

Varför får jag felkod Z80 – ogiltig checksumma?

Några vanliga anledningar är:

  • fel information signeras (inte UNH-UNT)
  • fel algoritm används (Inte SHA-256)
  • det är inte byte-representationen av checksumman som hexadecimalkodas i autacken.

Elektronisk signatur (krypterade checksumman)

Vilken krypteringsalgoritm ska användas?

RSA ska användas. Ofta görs checksummeberäkning och signering i ett steg och då brukar algoritmen benämnas SHA256WithRSA.

Vilket data ska signeras?

Det är byterepresentationen av checksumman (alltså inte den hexadecimalkodade representationen) som ska signeras.

Hur beräknar vi den elektroniska signaturen?

Beroende på vilken utvecklingsmiljö ni använder görs det i ett eller två steg. I vissa miljöer, till exempel Java, görs det i ett steg och då är det UNH-UNT som signeras, till exempel enligt nedan.

Signature sig = Signature.getInstance("SHA256WithRSA");
sig.initSign(signKey);
sig.update(unhTillUntString, 0, unhTillUntString.length);
byte [] bytes = sig.sign ();
I andra miljöer, till exempel Microsofts CryptoAPI skapas checksumman baserat på UNH-UNT och signaturen beräknas på byte-representationen av checksumman, till exempel enligt nedan.

bResult = CryptHashData(hHash, unhTillUntString, cbRead, 0 );
bResult = CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, pbSignature, &dwSigLen );

Vilken kodning ska användas av den binära signaturen i autacken?

Den krypterade kryptografiska checksumman (digitala signaturen) får inte kodas enligt base64, utan måste hexadecimalkodas. Det får inte finnas några mellanslag i det hexadecimalkodade värdet.

Vi är ännu inte redo att skicka EDIFACT-filer, men önskar få vår implementering av signaturen verifierad. Kan ni verifiera vår krypterade checksumma?

Nej, vi behöver hela EDIFACT-utväxlingen.

Vilken blockutfyllnadsalgoritm ska användas?

Utfyllnad sker med RSASSA-PKCS1-v1_5. Detta är troligen standardalternativet i den utvecklingsmiljö ni använder.

Finns det några kommandoradsverktyg för att signera/verifiera signaturer?

OpenSSL kan användas
openssl rsautl —sign
openssl rsautl —verify

Varför får vi felkod Z81 – ogiltig elektronisk signatur?

Orsaken kan till exempel vara att:

  • fel privat nyckel används, det vill saga inte den nyckel som användes för att signera certifikatbegäran
  • det inte är byte-representationen av checksumman (utan till exempel den hexadecimala representationen) som signeras
  • den elektroniska signaturen inte hexadecimalkodas i autacken
  • fel krypteringsalgoritm används. För API:er där signering sker i ett steg kan det till exempel bli SHA1withRSA och inte SHA256withRSA, om ni inte specifikt anger detta.

Autack-meddelandet

Finns det något exempel på vilken information som ska finnas i autack?

Vad ska anges i USH[2].0534 / USY[9].0534 (“Security Reference Number")?

Detta är en unik intern referns från USH till motsvarande USY-segment. I princip är det en räknare vars namn genereras av sändaren, men i praktiken räcker det med ett värde, till exempel SRN01 eftersom endast en signatur används.

Vad ska anges i USH[2].0511 (“Security party identification")?

Detta är ert Eori-nummer inklusive land-kod. Observera att det inte ska sammanblandas med certifikatets serienummer och det ska varken kodas med base-64 eller med hexadecimal.

Vad ska anges i USC[4].0536 (“Certificate reference")?

Detta är en base-64 kodning av certifikatets serienummer. Det är byte-representationen av serienumret som ska base-64 kodas. Ett vanligt fel är att istället använda den hexadecimalkodade representationen av serienumret som presenteras i en del certifikatvisningsverktyg. Ett annat vanligt fel är att använda EORI-nummer från certifikatets ämnes fält (SERIALNUMBER=, OU=, O=,C=,CN=..)

Vad ska anges i USC[4].0538 (“Key name")?

Detta är en base-64 kodning av nyckel-id för utfärdarcertifikatet. Detta används av Tullverket för att avgöra vilket certifikat som signaturen ska verifieras mot.

Som exempel ser värdet för certifikat utgivna av “CN=Swedish Customs Public CA 1.0, SERIALNUMBER=SE2021000969, OU=Only for authorized use, OU=Public Intermediate Certificate Authority, OU=Swedish Customs, O=Tullverket, C=SE" ut så här:
PS1IRSLAUC0cmps4EQMSDUL77f8=

Varför behövs certifikatets serienummer, nyckel-id för utfärdarcertifikat, checksumma och elektronisk signatur? Borde det inte räcka med elektronisk signatur?

Verifieringen innefattar följande steg:

  1. Checksumma beräknas på UNH-UNT med SHA-256. Denna checksumma jämförs med checksumman i autacken. Fel skulle upptäckas även om enbart verifiering gjordes av den elektroniska signaturen, men detta steg ger oss möjlighet att ge bättre felmeddelanden.
  2. Den publika nyckeln för certifikatet som pekas ut med serienummer och nyckel-id för utfärdare hämtas ut.
  3. Den elektroniska signaturen dekrypteras med den publika nyckeln som hämtades i föregående steg.
  4. Den dekrypterade elektroniska signaturen (=checksumman) jämförs med den beräknade checksumman.

Certifikatets serienummer serial number

Hur läser vi ut certifikatets serienummer?

Exakt hur detta görs beror på er utvecklingsmiljö, men det kan se ut ungefär så här i Java:

BigInteger serial = x509Certificate.getSerialNumber().
new Base64Encoder().encode(serial.toByteArray());
och så här i C#
System.Convert.ToBase64String(X509Certificate.GetSerialNumber());

Observera att certifikatets serienummer inte är samma som SERIALNUMBER i ämne (subject distinguished name) för certifikatet.

Vilken kodning ska användas för certifikatets serienummer i autacken?

Byte-representationen av serienumret ska kodas med base-64. Ett vanligt fel är att istället använda hexadecimalkodning eftersom många certifikatvisningsprogram presenterar serienumret i hexadecimalform. Ett annat vanligt fel är att base-64 koda den hexadecimala representationen istället för byte-representationen. I Unix kan ett hexadecimalt värde konverteras till base-64 med nedanstående kommando. Det kan användas för att verifiera att värde i genererad autack är korrekt:

echo "00 97 95 45 e3 c4 c2 59 ef " | xxd -r -p | openssl base64
AJeVRePEwlnv

Nyckel-id för utfärdarcertifikatet (authorityKeyIdentifier keyId)

Vad är nyckel-id för utfärdarcertifiktatet (authorityKeyIdentifier keyId) och hur används det?

Fältet authorityKeyIdentifier i ett certifikat används för att unikt identifiera vilket utfärdarcertifikat som har använts för att signera ett certifikat. Fältet authorityKeyIdentifier i ett certifikat svarar mot fältet subjectKeyIdentifier i motsvarande utfärdarcertifikatet. Fältet kan innehålla följande underliggande fält (se också RFC 5280).

  • keyIdentifier — innehåller en checksumma av utfärdarens publika nyckel (nyckel-id)
  • authorityCertIssuer — namnet på utfärdarcertifikat
  • authorityCertSerialNumber — serienummer för utfärdarcertifikatet

Publika nycklar bifogas inte i autack vid signering och därför måste Tullverket söka fram vilket certifikat som signaturen ska verifieras mot. Det underliggande fältet keyIdentifier (nyckel-id) används av Tullverket för att hitta detta certifikat. Serienummer är inte tillräckligt eftersom olika utfärdare kan ha samma serienummer. Se också avsnitt 4.2.1.1 för mer information.

Hur läser vi ut nyckel-id för utfärdarcertifikatet från vårt certifikat?

Läs ut det underliggande fältet keyIdentifier från certifikatfältet AuthorityKeyIdentifier och koda detta värde med base64. AuthorityKeyIdentifier återfinns i certifikatextensionen 2.5.29.35. Exakt hur man läser detta värde beror på vilken utvecklingsmiljö ni använder, men det kan se ut ungefär enligt nedan:

byte[] extvalue = x509Certificate.getExtensionValue("2.5.29.35");
DEROctetString oct = (DEROctetString) (new ASN1InputStream(new ByteArrayInputStream(extvalue)).readObject());
AuthorityKeyIdentifier keyId = new AuthorityKeyIdentifier((ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream(oct.getOctets())).readObject());
base64Encode(keyId.getKeyIdentifier());

Vilken kodning ska användas av nyckel-id för utfärdarcertifikatet i autacken?

Byte-representationen av nyckel-id för authorityKeyIdentifier ska kodas med base-64. Ett vanligt fel är att istället använda hexadecimalkodning eftersom många certifikatvisningsprogram presenterar fältet i hexadecimalform. Ett annat vanligt fel är att base-64-koda den hexadecimala representationen istället för byte-representationen. I Unix kan ett hexadecimalt värde konverteras till base-64 med nedanstående kommando. Det kan användas för att verifiera att värde i genererad autack är korrekt:

echo "3d 2d 48 45 22 c0 50 2d 1c 9a 9b 38 11 03 12 0d 42 fb ed ff" | xxd -r -p | openssl base64
PS1IRSLAUC0cmps4EQMSDUL77f8=

Dokumentation

Var hittar jag information om det PKI-baserade säkerhetskonceptet?

Läs mer på sidan EDI – Säkerhet.

Var hittar jag Tullverkets publika certifikat, utfärdarcertifikat och rotcertifikat?

Läs mer på sidan EDI – Säkerhet.

Var hittar jag autackspecifikationerna?

Läs mer om autackspecifikationerna på sidan SCTS-SC

Sidan uppdaterades:

Vad är ändrat: Språklig justering

Vi tar tacksamt emot förbättringsförslag men kan tyvärr inte svara på några frågor här.

Har du en fråga kan du i stället kontakta oss.


4000
Spamskydd med captcha * (obligatorisk)