Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Current »

Language

Note: This part of the documentation is in Norwegian only. An English version can be provided if needed.


Innhold på denne siden:

Relatert informasjon:



PKI Signering

Her finner du dokumentasjon på hva en IPS signering er og fungerer, hvordan du bygger opp en signerings forespørselen og tolker responsen. Du finner også informasjon om de forskjellige signeringsformatene som er støttet, hvordan dette brukes og hvordan man trygt kan overføre dokumentet til klientsiden.

Merk at eksempelkodene i denne siden er kun ment som illustrasjonseksempeler på kjernemekanismene, og bør "robustifieres"/justeres med feilhåndtering og/eller andre nødvendige tilpasninger før en ev. produksjonssetting.


Hva er en IPS signering?

En signering gjennom IPS gir en sluttbruker mulighet for å se på og signere et dokument med sin PKI. Dokumentet tilgjengeliggjøres på brukerstedets server, og lastes ned til klienten. På klienten kan sluttbrukeren se på dokumentet gjennom sin installerte "viewer" for det aktuelle dokumentformatet før det signeres. Når dokumentet er signert, vil IPS verifisere signaturen, og returnere signatur og sertifikat tilbake til brukerstedet. På brukerstedssiden vil brukerstedet kunne sette sammen den angitte SDO typen basert på disse elementene, og verifisere signaturen/SDO'en om ønskelig. Signaturformatene støttes gjennom en SignatureProvider plugin arkitektur. Etter hvert som det tilkommer støtte for flere signaturformater, kan disse lastes ned fra disse sidene. Man kan også implementere egne plugins hvis ønskelig, men kravet til input data til eventuelle egenutviklede plugins må samsvare med en av de eksisterende SignatureProvider plugin'ene.


Hvordan er prinsippene ift What-you-see-is-what-you-sign implementert i IPS ?

For å kunne sannsynliggjøre at det du ser er det du signerer (WYSIWYS-prinsippet), er det viktig å ha en så nære knyttning som mulig mellom "se-på prosessen" og signeringsprosessen. Helst bør dette skje i en egen ekstern "signerings-terminal" som er lukket og beskyttet fra PC'en ellers. Allikevel må man ha tilitt til denne signerings-terminalen, og det får man gjerne gjennom dokumentasjon, sertifiseringer og andre bekreftelser fra anerkjente leverandører.

For å kunne tilby en signeringsløsning på Internet uten en slik "signerings-terminal", er det viktig at de som bruker signeringsløsningen og de som tilbyr signering gjennom en slik løsning, kjenner til hvordan man i størst mulig grad sannsynliggjør at det du faktisk ser er det du faktisk signerer. Derfor er det viktig at denne informasjonen er tilgjengelig, og at man da selv kan ta stilling til om man syntes disse mekanismene sannsynliggjør dette i tilstrekkelig grad.

I IPS er dette sannsynliggjort ved at dokumentet lastes ned på klienten, og inn i samme prosess som skal styre den faktiske signeringen mot Smartkortet. Dataene fra samme prosess tilgjengeliggjøres for visning, sammen med mime-typen brukerstedet selv har angitt for innholdet (f.eks. "application/pdf"). På denne måten startes så det aktuelle programmet sluttbrukeren har installert for den gitte mime-typen (f.eks. Adobe Reader), og dokumentet vises i dette programmet. Når sluttbrukeren har sett på dokumentet/filen som skal signeres, taster brukeren PIN-kode, og korrekt preprosessert DTBS (Data-To-Be-Signed) i forhold til angitt signaturformat over de samme dataene signeres. 


SignatureProvider plugin

Signaturformatsøttten i integrasjonsbibliotekene er implementert gjennom en såkalt SignatureProvider plugin arkitektur. En SignatureProvider plugin tilbyr encoding og verifisering av sine relevante formater og delstrukturer. F.eks. vil BPESIG0101 plugin, som støtter basic PKCS#7 SDO'er, tilby støtte for encoding av alle relevante delstrukturer som brukes i en basic PKCS#7 signering. Det samme gjelder for de andre signaturformatene.

SignatureProvider kode pattern for SDO generering vil være slik: 

   // get the correct provider instance
   SignatureProvider sp = SignatureProvider.getInstance([format]);
   sp.initializeForEncode([encoding mode]);

   // add all required parameters
   sp.setParam([dataparam name-1],[value-1]);
   ..
   sp.setParam([dataparam name-n],[value-n]);

   // encode the given structure
   byte[] encodedData = sp.encode();

SignatureProvider kode pattern for SDO verifisering vil være slik: 

   // get the correct provider instance
   SignatureProvider sp = SignatureProvider.getInstance([format]);
   sp.initializeForVerify([verification mode]);

   // add all required parameters
   sp.setParam([dataparam name-1],[value-1]);
   ..
   sp.setParam([dataparam name-n],[value-n]);
  
   // verify the given structure
   boolean verifiedOk = sp.verify();

Under følger en global liste over alle dataparameter typer. 

Følgende dataparametere er felles for alle BPESIG SignatureProvider plugins

ParameterTypeBeskrivelse
DTBSbyte[]Data-To-Be-Signed - dette er de faktiske binære dataene som signeres etter all nødvendig preprosessering, uten padding.
CONTENTbyte[]Eksakt binær representasjon av dokumentet/filen som skal signeres.
CONTENT_SHA1_DIGESTbyte[]Hash av CONTENT i henhold til spesifisert hash-algoritme
CMS_SIGNED_ATTRIBUTESbyte[]CMS SignedAttributes. Den binære representasjonen av en PKCS#7 v1.5 SignedAttributes som skal brukes ved signering/verifisering.
CLAIMED_SIGNING_TIMEDate (Java)/
DateTime (.NET)
Datoobjekt som representerer brukerstedets oppfatning av tidspunkt for signering.
CERTIFICATEbyte[]Binær representasjon av X509 Sertifikatet som skal brukes ved signering.
SIGNATUREbyte[]Binør representasjon av signaturen. For en 1024 bits RSA signering vil denne eksempelvis være 128 bytes lang.
CMS_SIGNED_DATA_OBJECTbyte[]CMS SignedDataObject. Den binære representasjon av en PKCS#7 v1.5 SignedDataObject som skal brukes ved signering/verifisering.
SEID_INCLUDE_SIGNEDOBJECTString ("1"/"0")1 hvis CONTENT skal være med i SEID_SDO'en, 0 hvis ikke
SEID_INCLUDE_HASHEDDATAString ("1"/"0")1 hvis HashedData elementet skal være med i SEID_SDO'en, 0 hvis ikke
PDF_SIGNED

SIGNATURE_CONTEXTcnl.wips.remote.tools.crypto.SignatureContextTilstandsholder objekt gjennom de forskjellige fasene av encoding. Et tomt SignatureContext objekt opprettes gjennom å kalle SignatureProvider.createSignatureContext() på den aktuelle SignatureProvideren
VISIBLE_SIGNATURE_PAGEStringSide nummer som den synlige signaturen skal ligge på
VISIBLE_SIGNATURE_XStringDen horisontale posisjonen til den synlige signaturen
VISIBLE_SIGNATURE_YStringDen vertikale posisjonen til den synlige signaturen
VISIBLE_SIGNATURE_WIDTHStringBredden til den synlige signaturen
VISIBLE_SIGNATURE_HEIGHTStringHøyden til den synlige signaturen
REASONStringTekstlig beskrivelse av grunn/årsak til at signaturen lages.
SIGNED_LOCATIONStringTekstlig beskrivelse av signeringssted.


Under følger en global liste over alle encoding modes

Følgende encoding mode identifikatorere er felles for alle BPESIG SignatureProvider plugins

ParameterBeskrivelse
DTBSData-To-Be-Signed - genererer de faktiske binære dataene som signeres etter all nødvendig preprosessering, uten padding.
CMS_SIGNED_ATTRIBUTESCMS SignedAttributes. Genererer den binære represenatsjonen av en PKCS#7 v1.5 SignedAttributes som skal brukes ved signering.
CMS_SIGNED_DATA_OBJECTCMS SignedDataObject. Genererer den binære represenatsjonen av en PKCS#7 v1.5 SignedDataObject som skal brukes ved signering.
SEID_SDO_BASICGenererer den binære representasjonen av en SEID_SDO_Basic XML struktur.
PDF_SIGNEDGenererer den signerte PDF'en.


Under følger en global liste over alle verification modes

Følgende verification mode identifikatorere er felles for alle BPESIG SignatureProvider plugins

ParameterBeskrivelse
CMS_SIGNED_DATA_OBJECT_INTEGRITYVerifiserer signatur objektets integritet. Dvs at strukturen i seg selv blir verifisert; signatur mot innhold og innhold i signed attributes, integretet og levetid på sertifikat, men ingen revokeringssjekk.
SEID_SDO_BASIC_CMS_INTEGRITYVerifiserer det interne CMS signatur objektets integritet i SEID_SDO'en. Dvs at den interne CMS strukturen i seg selv blir verifisert; signatur mot innhold og innhold i signed attributes, integretet og levetid på sertifikat, men ingen revokeringssjekk.
PDF_SIGNEDVerifiserer det interne PDF dokumentet opp mot signaturen, integretet og levetid på sertifikat, men ingen revokeringssjekk eller sjekk mot CA sertifikat.

Signaturformater

Følgende signatur formater støttes av IPS:

VerdiFra versjonBeskrivelse
BPESIG01011.0.1CMS basert signatur basert på PKCS#7, v1.5. Gir mulighet for å inkludere claimed signing-time i signatur grunnlaget (signed-attributes)
BPESIG02011.0.1CMS basert signatur basert på ETSI 101 733 v1.7.3. Dataene signeres og formateres iht CAdES-BES formatert signaturer. Gir mulighet for å inkludere claimed signing-time i signatur grunnlaget.
BPESIG03011.0.1CMS og XML basert signatur. Dataene signeres og formateres iht SEID SDO Basic (Type 1) profilen.
BPESIG04011.0.3Adobe PDF signatur, usynlig signatur.
BPESIG04021.0.3Adobe PDF signatur, visuelt synlig signatur i dokumentet

Du finner mer informasjon om de ulike signaturformatene lenger ned.

Dokumentformater

IPS har ikke noe teknisk forhold til formatet på dokumentet utover mime-typen som anngis for det for det aktuelle formatet av brukerstedet selv. Dette betyr at man i prinsippet står fritt til å signere alle type dokumenter/filer, fra PDF'er og Word dokumenter til .exe filer og .zip filer. "Viewer" prosessen blir da håndtert slik den aktuelle applikasjonen for den gitte mime-typen håndterer det. Av sikkerhetsmessige årsaker har Buypass begrenset IPS til å kun signere PDF (application/pdf) og rene tekstfiler (text/plain). Hvis det er behov for å kunne signere andre type formater, kontakt Buypass for videre diskusjon.

Nedlasting av dokumenter til sluttbruker

Som tidligere nevnt, lastes det aktuelle dokumentet over til kundens PC i forkant av selve signeringen. Det finnes det flere varianter å tilgjengeliggjøre dokumentet på. Dokumentet må på en eller annen måte tilgjengeliggjøres for signeringsappleten, slik at denne kan lastes ned for visning- og signering. Det finnes følgende alternativer for tilgjengeliggjøring:

  1. Tilgjengeliggjøre dokumentet på åpen, ikke-gjettbar/uforutsigbar, URL
  2. Tilgjengeliggjøre dokumentet på en sesjonsbasert URL. Sesjonscookien sendes da med i forespørselen til IPS
  3. Tilgjengeliggjøre en kryptert (3DES/168bit) utgave dokumentet på en åpen eller sesjonsbasert URL. Dekrypteringsnøkkelen (og ev. sesjonscookien) sendes da med i forespørselen til IPS. WIRI tilbyr støttefunksjonalitet for kryptering, nøkkelgenering og base64 encoding av dokumenter som tilgjengeliggjøres på denne måten.
  4. Sende dokumentet med i forespørselen til IPS. Dette anbefales kun for små dokumenter. Total maks størrelse på en forespørsel til IPS er 256kb, men det anbefales uansett ikke å sende større dokumenter enn 3-5kb via IPS, da dokumentet må lastes opp (x1) og ned (x2) 3 ganger før det er "fremme" hos sluttbrukeren.

Hvis dokumentet tilgjengeliggjøres på Internet, bør dokumentet tilgjengeliggjøres på en SSL adresse. Alternativt krypteres som i alternativ 3), og tilgjengeliggjøres over http.


SignaturFormat BPESIG0101 - PKCS#7 v1.5 SDO

BPESIG0101 som signaturformat er basert på PKCS#7 v1.5 / RFC 2315. Utover det som er påkrevd, inkluderes også såkalt Claimed Signing Time som i dette tilfellet er brukerstedets oppfatning av signeringstidspunktet.

Tabellen under viser hvilke felter som er påkrevd for de forskjellige relevante operasjonene for BPESIG0101 SignatureProvider. Se kapittelet om SignatureProvider for detaljert beskrivelse av hva de forskjellige parameterne betyr.

ModusEncoding/Verification namePåkrevde FelterOverordnet beskrivelse
EncodingCMS_SIGNED_DATA_OBJECTCONTENT
CLAIMED_SIGNING_TIME
CERTIFICATE
SIGNATURE
Genrerer hele PKCS#7 SDO'en
VerifiseringCMS_SIGNED_DATA_OBJECT_INTEGRITYCMS_SIGNED_DATA_OBJECTVerifiserer integriteten i PKCS#7 SDO'en (ingen revokeringssjekk)


Under er et kodeeksempel på sammensetting av en PKCS#7. Eksempelet er basert på at man har fått tilbake signatur og sertifikat etter signering, og at man har det signerte dokumentet og signeringstidspunkt tilgjengelig. 

  byte[] document = // the document
  byte[] signature = // the signature
  byte[] certificate = // the encoded certificate
  Date signingTime = // the given signingTime

  // get the BPESIG0101 signature provider
  SignatureProvider sp = SignatureProvider.getInstance("BPESIG0101");

  // initialize for encoding of the PKCS#7 signature SDO
  sp.initializeForEncode("CMS_SIGNED_DATA_OBJECT");

  // add required parameters
  sp.setParam("CONTENT",              document); // the excact binary representation
  sp.setParam("CLAIMED_SIGNING_TIME", signingTime); // same as the SigningTime sent to IPS
  sp.setParam("CERTIFICATE",          certificate);  // certificate from IPS
  sp.setParam("SIGNATURE",            signature); // signature from IPS

  // get the encoded PKCS#7 signature SDO
  byte[] pkcs7 = sp.encode();


  Under er et kodeeksempel på verifisering av et signert dokument (verifisering av PKCS#7'en).

  byte[] pkcs7 = // the signature, or from previous sample

  // get the BPESIG0101 signature provider
  SignatureProvider sp = SignatureProvider.getInstance("BPESIG0101");

  // initialize for signature verification of the PKCS#7 signature SDO
  sp.initializeForVerify("CMS_SIGNED_DATA_OBJECT_INTEGRITY");

  // add required parameters (the signature)
  sp.setParam("CMS_SIGNED_DATA_OBJECT", pkcs7);

  // verify SDO integrity
  boolean verifiedOk = sp.verify();

SignaturFormat BPESIG0201 - ETSI TS 101 733 CAdES-BES SDO

BPESIG0201 som signaturformat er basert på PKCS#7 v1.5 / RFC 2315, men inkluderer i tillegg påkrevde elementer for å være konform med ETSI TS 101 733 CAdES-BES. Tilleggs elementene er hentet fra ESS RFC263 (Enhanced Security Servies), og består av signing-certificate elementet eller other-signing-certificate. IPS inkluderer signing-certificate elementet, som kort fortalt består av en SHA-1 Hash over signerers sertifikat. Dette inkluderes i signaturgrunnlaget for å sikre en entydig knytning mellom signatur og et faktiske sertifikatet som ble brukt. Utover det som er påkrevd, inkluderes også Claimed Signing Time som i dette tilfellet er brukerstedets oppfatning av signeringstidspunktet.

Tabellen under viser hvilke felter som er påkrevd for de forskjellige relevante operasjonene for BPESIG0201 SignatureProvider. Se kapittelet om SignatureProvider for detaljert beskrivelse av hva de forskjellige parameterne betyr.

ModusEncoding/Verification namePåkrevde FelterOverordnet beskrivelse
EncodingCMS_SIGNED_DATA_OBJECTCONTENT
CLAIMED_SIGNING_TIME
CERTIFICATE
SIGNATURE
Genrerer hele CAdES-BES SDO'en
VerifiseringCMS_SIGNED_DATA_OBJECT_INTEGRITYCMS_SIGNED_DATA_OBJECTVerifiserer integriteten i CAdES-BES SDO'en (ingen revokeringssjekk)


Under er et kodeeksempel på sammensetting av en CAdES-BES SDO. Eksempelet er basert på at man har fått tilbake signatur og sertifikat etter signering, og at man har det signerte dokumentet og signeringstidspunkt tilgjengelig. 

  byte[] document = // the document
  byte[] signature = // the signature
  byte[] certificate = // the encoded certificate
  Date signingTime = // the given signingTime

  // get the BPESIG0201 signature provider
  SignatureProvider sp = SignatureProvider.getInstance("BPESIG0201");

  // initialize for encoding of the CAdES-BES signature SDO
  sp.initializeForEncode("CMS_SIGNED_DATA_OBJECT");

  // add required parameters
  sp.setParam("CONTENT",              document); // the excact binary representation
  sp.setParam("CLAIMED_SIGNING_TIME", signingTime); // same as the SigningTime sent to IPS
  sp.setParam("CERTIFICATE",          certificate);  // certificate from IPS
  sp.setParam("SIGNATURE",            signature); // signature from IPS

  // get the encoded CAdES-BES SDO
  byte[] pkcs7 = sp.encode();


Under er et kodeeksempel på verifisering av et signert dokument (verifisering av CAdES-BES SDO'en). 

  byte[] pkcs7 = // the signature, or from previous sample

  // get the BPESIG0201 signature provider
  SignatureProvider sp = SignatureProvider.getInstance("BPESIG0201");

  // initialize for signature verification of the CAdES-BES signature SDO
  sp.initializeForVerify("CMS_SIGNED_DATA_OBJECT_INTEGRITY");

  // add required parameters (the signature)
  sp.setParam("CMS_SIGNED_DATA_OBJECT", pkcs7);

  // verify SDO integrity
  boolean verifiedOk = sp.verify();

SignaturFormat BPESIG0301 - SEID-SDO-Basic

BPESIG0301 som signaturformat er basert på SEID-SDO-Basic profilen, som igjen er basert på PKCS#7 v1.5 / RFC 2315, men inkluderer i tillegg påkrevde elementer for å være konform med ETSI TS 101 733 CAdES-BES - som er påkrevd i SEID standarden. Tilleggs elementene er hentet fra ESS RFC263 (Enhanced Security Servies), og består av signing-certificate elementet eller other-signing-certificate. IPS inkluderer signing-certificateelementet, som kort fortalt består av en SHA-1 Hash over signerers sertifikat. Dette inkluderes i signaturgrunnlaget for å sikre en entydig knytning mellom signatur og et faktiske sertifikatet som ble brukt. Utover det som er påkrevd, inkluderes også Claimed Signing Time som i dette tilfellet er brukerstedets oppfatning av signeringstidspunktet.

SEID spesifiserer flere sett med profiler. BPESIG0301 er i.h.t. SEID-SDO-Basic profilen.

Tabellen under viser hvilke felter som er påkrevd for de forskjellige relevante operasjonene for BPESIG0301 SignatureProvider. Se kapittelet om SignatureProvider for detaljert beskrivelse av hva de forskjellige parameterne betyr.

ModusEncoding/Verification namePåkrevde FelterOverordnet beskrivelse
EncodingSEID_SDO_BASICCONTENT
CLAIMED_SIGNING_TIME
CERTIFICATE
SIGNATURE
MIME_TYPE
MERCHANT_DESC
CHARACTER_ENCODING
(SEID_INCLUDE_HASHEDDATA)
(SEID_INCLUDE_SIGNEDOBJECT)
Genrerer hele SEID SDO'en (XML)
VerifiseringSEID_SDO_BASIC_CMS_INTEGRITYSEID_SDO_BASICVerifiserer integriteten i CMS delen av SDO'en (ingen revokeringssjekk)


Under er et kodeeksempel på sammensetting av en SEID SDO. Eksempelet er basert på at man har fått tilbake signatur og sertifikat etter signering, og at man har det signerte dokumentet og signeringstidspunkt tilgjengelig. 

byte[] document = // the document
  byte[] signature = // the signature
  byte[] certificate = // the encoded certificate
  Date signingTime = // the given signingTime

  // get the BPESIG0301 signature provider
  SignatureProvider sp = SignatureProvider.getInstance("BPESIG0301");

  // initialize for encoding of the SEID SDO
  sp.initializeForEncode("SEID_SDO_BASIC");

  // add required parameters
  sp.setParam("CONTENT",                document); // the excact binary representation
  sp.setParam("CLAIMED_SIGNING_TIME",   signingTime); // same as the SigningTime sent to IPS
  sp.setParam("CERTIFICATE",            certificate);  // certificate from IPS
  sp.setParam("SIGNATURE",              signature); // signature from IPS
  sp.setParam("MIME_TYPE",              "application/pdf"); // the content is a PDF document
  sp.setParam("MERCHANT_DESC",          "Same description as shown in the IPS GUI"); 
  sp.setParam("CHARACTER_ENCODING",     "UTF-8"); // we want UTF-8 XML encoding
  sp.setParam("SEID_INCLUDE_HASHEDDATA","1"); // we want to include the HashedData element
  sp.setParam("SEID_INCLUDE_SIGNEDOBJECT","0"); // we dont want to include the doc

  // get the encoded SEID SDO
  byte[] seidSDO = sp.encode();

  // seidSDO is the SEID-SDO XML - convert it to a string, for joy
  String theXML = new String(seidSDO, "UTF-8");

Under er et kodeeksempel på verifisering av et signert dokument (verifisering av CMS delen av SEID SDO'en).


  byte[] seidSDO = // the signature, or from previous sample

  // get the BPESIG0301 signature provider
  SignatureProvider sp = SignatureProvider.getInstance("BPESIG0301");

  // initialize for signature verification of the CMS part of the SDO
  sp.initializeForVerify("SEID_SDO_BASIC_CMS_INTEGRITY");

  // add required parameters (the signature/SDO)
  sp.setParam("SEID_SDO_BASIC", seidSDO);

  // verify SDO integrity
  boolean verifiedOk = sp.verify();

SignaturFormat BPESIG0401 - PDF signatur, usynlig signatur

BPESIG0401 som signaturformat er basert på Adobes PDF signeringsformat. Signaturene som er opprettet ved hjelp av BPESIG0401 er ikke synlige i dokumentet ved f.eks. print, men sjekkes/verifiseres gjennom en PDF viewer (som Adobe Reader).

SignaturFormat BPESIG0402 - PDF signatur, synlig signatur

BPESIG0402 som signaturformat er basert på Adobes PDF signeringsformat. Signaturene som er opprettet ved hjelp av BPESIG0402 er synlige i dokumentet ved f.eks. print, og kan sjekkes/verifiseres gjennom en PDF viewer (som Adobe Reader).


Sammensetting av forespørselen

Sammensetting av signeringsforespørselen skjer typisk når en sluttbruker ønsker å signere noe. Ved sammensetting av en signeringsforespørsel, er det flere ting man må ta stilling til:

  • Hvordan skal dokumentet tilgjengeliggjøres for sluttbrukeren?
  • Påstått signeringstidspunkt
  • Signaturformat
  • Dokumentformat/MIME-type
  • Hvilke returverdier du ønsker om sluttbrukeren
  • Hvilket brukergrensesnitt du ønsker å bruke
  • Retur URL (ved redirigerte forespørseler)

Pr des-08 er det kun Smartkort med PKI som kan brukes til signering. 

Påstått signeringstidspunkt anngis gjennom MerchantSigningTime elementet.

Brukergrensesnitt kode anngis gjennom RequestAttribute elementet.

Retur URL anngis i ResponseUrl elementet.

Returverdier anngis gjennom ResponseAttribute elementet. Data om brukeren blir returnert gjennom IdToken elementet i responsen.

Støttebiblioteket vil hjelpe deg med de resterende påkrevde elementene.

Under er et JSP eksempel på en komplett sammensatt forespørsel, hvor vi tilgjengeliggjør dokumentet på en sesjonsbasert URL, kryptert. Nøkkelen og sesjonscookien utveksels i forespørselen til IPS, slik at innholdet i praksis kun kan leses av IPS klienten. Vi ønsker å få fødselsnummeret i retur, og vi ønsker også å bruke et "FULLSIZE" brukergrensesnitt, og må derfor anngi dette gjennom RequestAttribute elementet. Dokumentet er et PDF dokument, og vi bruker derfor mime-typen "application/pdf". Eksempelet under spesifiserer et BPESIG0201 signaturformat, som er komform med ETSI 101 733 CAdES-BES signaturer. 


byte[] document = buf; // the excact binary representation of the document
String sessionId = request.getSession().getId();
String sessionCookie = "JSESSIONID=" + sessionId;

// generate a required SHA-1 hash for the document
MessageDigest dig = MessageDigest.getInstance("SHA1");
dig.update(document);
byte[] hash = dig.digest();

// generate a base64 encoded encryption key
// that we're gonna use to encrypt the document
String b64EncryptionKey = BxCrypto.generateBase64EncodedKey();

// encrypt the document
byte[] encryptedDocument = BxCrypto.
	encryptDataWithBase64EncodedKey(b64EncryptionKey, document);

// make the document available on session, so that the
// getcontent.jsp can reach it
request.getSession().setAttribute("document", encryptedDocument);
request.getSession().setAttribute("document-type", "application/pdf");

// build request data
BxElement srd = new BxElement("SignRequestData");
srd.addElement("RequestId", BxCrypto.generateUid());
srd.addElement("ResponseUrl", 
	"http://mysite.com/processsignresponse.do");

// choose fullsize GUI
srd.addElement("RequestAttribute",    new String[] 
	{"name"}, new String[] {"ips:GUI"});
srd.getElement("RequestAttribute", 0).setValue("WIPSGUI-FULLSIZE");


// add the transfer encryption key
srd.addElement("TransferEncryptionKey", new String[] 
	{"Encoding"}, new String[] 
	{"ips:Base64"});
srd.getElement("TransferEncryptionKey", 0).
	setValue(b64EncryptionKey);

// add the session cookie
srd.addElement("ContentCookie", sessionCookie);

// add the current time
String claimedSigningTime = BxElement.getDatTime();
srd.addElement("MerchantSigningTime", claimedSigningTime);

// add the signature format, we need compliance with
// ETSI 101 733 CAdES-BES signatures
srd.addElement("SignatureFormat", "BPESIG0201");

// add the document format/mime-type
srd.addElement("ContentMimeType", "application/pdf");

// add the document URL
srd.addElement("ContentUri", "http://mysite.com/getcontent.jsp?what=document");

// add the SHA-1 hash over the document
srd.addElement("ContentHash", 
	new String[] {"Encoding"}, 
	new String[] {"ips:HexEncoding"});
// If we want to use SHA2, the Algorithm attribute must be added, so use instead:
//srd.addElement("ContentHash", 
//	new String[] {"Encoding", "Algorithm"}, 
//	new String[] {"ips:HexEncoding", "ips:SHA256"});

srd.getElement("ContentHash", 0).
	setValue(StrFormat.hexify(hash));	 	 

// add the description
srd.addElement("ContentDescription", 
	new String[] {"Encoding"}, 
	new String[] {"ips:Plain"});
srd.getElement("ContentDescription", 0).
	setValue("Signering av et eksempel dok");

BxRequest req = new BxRequest("SignRequest", srd, true);

// get the form data
String pse = req.getPSE();
String e = req.getE();

// make request object available on session
request.getSession().setAttribute("signreq", req);

Relevante elementer å forholde seg til ifm sammensetting av en signeringsforespørsel er:

  • SignRequest
  • SignRequestData
  • SignResponseData
  • ResponseURL
  • RequestAttribute
  • ResponseAttribute

Tilgjengeliggjøring av dokumentet for sluttbrukeren

Dokumentet må tilgjengeliggjøres for signeringsklienten som nevnt over. Under er et eksempel på hvordan en "getcontent.jsp", som det refereres til i eksempelet over, kan se ut. Eksempelet er en JSP fil, som kjøres på Tomcat (ref work-around for tomcat i eksempelet under). Koden under er kun ment som et eksempel og for å komplettere forståelsen av sammenhengen i de vedlagte eksempelkodene. 

getcontent.jsp

<%

// get content and content type from session, 
// based on the "what" request parameter
byte[] content = (byte[])request.getSession().
	getAttribute(request.getParameter("what"));
String contentType = (String)request.getSession().
	getAttribute(request.getParameter("what") + "-type");
if(content == null){
	response.sendError(404, "requested content not found");
	return;
}

// reset header to get around charset bug 24970 for tomact 4.1.x 
// (http://www.mail-archive.com/tomcat-dev@jakarta.apache.org/msg61011.html) 
response.reset();

response.setContentType(contentType);
response.setContentLength(content.length);
response.getOutputStream().write(content);
response.getOutputStream().flush();
%>

Redirigering/sending av forespørselen til IPS

Når signeringsforespørselen er satt sammen og klar, må den sendes til IPS. Dette gjøres ved å sende PSE og E parameteren til IPS, sammen med OP (operasjonstype) og M (merchantID) parameterene i en HTML form. HTML form'en returneres tilbake til nettleseren, og sendes automatisk til IPS (v.h.a. "auto-submit"/submit på body-on-load eventen). Under er et eksempel på en side som gjør dette basert på "pse" og "e" variablene fra det første eksempelet over. I eksempelet under er merchantID=32. 

<html>
  <body 
    onload="javascript:document.getElementById('signForm').submit()">
    <form id="signForm" 
      action="https://secure.test4.buypass.no/wips/service" 
      method="POST">
        <input type="hidden" name="PSE" value="<%=pse%>">
        <input type="hidden" name="E" value="<%=e%>">
        <input type="hidden" name="M" value="32">
        <input type="hidden" name="op" value="BXSIGN">
    </form>
  </body>
</html>

Javascript støtte er påkrevd i nettleseren for bruk av IPS.

Mottak og tolking av responsen

Returdataene fra signeringen "kommer tilbake" til brukerstedet på samme måte som de ble sendt til IPS. Det vil si at IPS vil returnere signeringsresponsen tilbake til nettleseren, som vil bli POST'et tilbake til brukerstedet på anngitt adresse (ResponseUrl).

Parameteren som inneholder returverdiene heter PE. Denne leses typisk ved å kalle 

String pe = request.getParameter("PE");

i en JSP fil. For å kunne dekryptere denne, må det korresponderende BxRequest objektet være tilgjengelig. I eksempelene over, ble dette lagt på sesjonsobjektet for å kunne brukes til dekryptering av responsen. Her er et eksempel på lesing, dekryptering og parsing: 

// parse response data
BxResponse res = new BxResponse(request.getParameter("PE"));
res.setRequestContext((BxRequest)request.getSession().
  getAttribute("signreq"));
res.parse();

I koden over har nå BxRequest objektet fra sesjonen blitt tilordnet responsen, og responsen er dekryptert og parset. Neste steg blir å lese ut dataene fra responseobjektene. 

// get id response object
BxElement signResponseData = res.getElement("SignResponseData");

// get response status
String status = signResponseData.getElement("ResponseCode").getValue();

out.println("Status: " + status + "");

if(status.equals("ips:SUCCESS")){

	// get the base64 encoded certifcate from response
	String scert = signResponseData.getElementValue("Certificate");

	// get the base64 encoded signature from response
	String ssign = signResponseData.getElementValue("Signature");
}

Sertifikat og signatur er nå hentet ut å ligger i scert og ssign variablene.

Sammensetting og verifisering av signaturobjektene

Under er et eksempel på sammensetning av SDO'en basert på response dataene fra eksempelet over. Etter å ha lest ut response dataene (i eksempelet over), bruker vi sertifikatet, signaturen, dokumentet og signeringstidspunktet til å generere PKCS#7 strukturen. Deretter verifiseres denne. 

byte[] content = // the document 
Date signingTime = // the signing time

// ...

if(status.equals("ips:SUCCESS")){

	// we want to encode a PKCS#7/CAdES-BES signature
	SignatureProvider ep = SignatureProvider.getInstance("BPESIG0201");
	ep.initializeForEncode("CMS_SIGNED_DATA_OBJECT");

	// add all required parameters
	ep.setParam("CONTENT", content);
	ep.setParam("CLAIMED_SIGNING_TIME", signingTime);
	ep.setParam("CERTIFICATE", (byte[])Base64Util.decodeBase64(scert));
	ep.setParam("SIGNATURE", (byte[])Base64Util.decodeBase64(ssign));

	// encode the structure	
	byte[] pkcs7 = ep.encode();

	// we also want to verify the pkcs7 signature
	SignatureProvider vp = SignatureProvider.getInstance("BPESIG0201");
	vp.initializeForVerify("CMS_SIGNED_DATA_OBJECT_INTEGRITY");

	vp.setParam("CMS_SIGNED_DATA_OBJECT", pkcs7);

	boolean verifiedOk = vp.verify();
		
	BxElement idTokenData = null;
	BxElement idToken = signResponseData.getElement("IdToken");
	idTokenData = idToken.getElement("IdTokenData");

	// dump results	
	out.println("Signed by " + idTokenData.getElement("FirstName").
		getValue() + " " + idTokenData.getElement("LastName").
		getValue() + "");
	out.println("Signature verified OK: " + verifiedOk+ "");
	out.println("PKCS7 size: " + pkcs7.length + "");
}



  • No labels