Document toolboxDocument toolbox

Using BankID Java Server

Application start-up code

Initialising BankID Java Server includes the following:

  • Registering a HSM PKCS#11 driver (If using HSM).
  • Loading/Registering merchant contexts. This must be done for each merchant that is supposed to use the same instance of BankID J Server.
  • Retrieving a "no.bbs.server.implementation.BIDFacade" instance for each merchant. This is the "handle" which exposes the BankID Server API methods to use.


The merchant application needs to perform the following actions.

  • Get the BIDFactory instance
  • For each merchant to configure call one of the following two methods:
  • loadBankIDContext(...) If using a configuration file
  • registerBankIDContext(...) If NOT using a configuration file

 

// Get the BIDFactory instance
BIDFactory factory = BIDFactory.getInstance();
  
// Registering a PCKS#11 driver in BankID Server. The loadPKCS11Adapter
// method takes the fully qualified path of the NativeCryptoki.dll(.so)
// and the PKCS#11 driver as input.
// NativeCryptoki.dll (.so) is the JNI-wrapper module used by BankID
// Server. NativeCryptoki loads the input PKCS#11 driver. This PKCS#11
// driver (or so-file) must be the PKCS#11 driver to the HSM that the
// merchant keys are stored in. If you are not using HSM's to store your
// keys then ignore this line.
// This method MUST ONLY be called once. 1 BankID Server process may only
// load 1 PKCS#11 driver. This is to avoid conflicts, and means that the
// BankID Server can only communicate with HSM's from 1 vendor at a time.
factory.loadPKCS11Adapter("/opt/drivers/NativeCryptoki.dll", "/opt/drivers/bp201w32HSM.dll");
  
try {
    // Configuring a merchant that has its BankID settings in a property
    // file merchant.props. The first parameter (value="/opt/merchant/") is
    // the directory where "merchant" has placed its configuration files. If
    // this value is null then merchant.props MUST be located in BankID
    // Server's classpath.
    factory.loadBankIDContext("/opt/merchant/", "merchant", "merchant_pwd");
    // OR
    // Configuring a merchant passing all the mandatory configuration
    // parameters through the API. No configuration file is needed when
    // calling thefollowing method.
    MerchantConfig mConfig = new MerchantConfig();
    mConfig.setGrantedPolicies("2.16.578.1.16.1.9.1,2.16.578.1.16.1.11.2.1");
    mConfig.setKeystorePassword("minbank_pwd");
    mConfig.setMerchantKeystore("/opt/merchant/merchant.bid");
    mConfig.setMerchantName("merchant");
    mConfig.setWebAddresses("www.merchant.com,192.168.0.1");
    mConfig.setCommTimeout("20000"); // Communication Socket timeout
    mConfig.setTokenUserPIN("123456"); // Only if merchant is using HSM
    // the following two params can be added to enable logging
    //mConfig.setLogPropFileLocation("/opt/log/log4j.props");
    //mConfig.setLogAppender("Merchant1Appender");
  
    ContextInfo minBankContextInfo = factory.registerBankIDContext(mConfig);
} catch(BIDException be) {
    int errorCode = be.getErrorCode();
    String errorMessage = be.getMessage();
    String methodIdentifier = be.getMethodIdentifier();
}
   
// To start using the BankID Server API on behalf of "merchant" the
// merchant application has to get a
// "no.bbs.server.implementation.BIDFacade" passing the merchant context
// key (which is the merchantName "merchant")
BIDFacade minFacade = factory.getFacade("merchant");

Authentication and Signing processes

Every BankID use-case, authentication or signing, starts with the merchant will retrieve a helper uri and a clientID, see [IMPLW]
Please see [IMPL] for a full description of the authentication and signing processes.

Authentication process – BankID on Mobile

// BankID authentication. This example builds upon the earlier code excerpts using
// "merchant"
 
 
// step 1: Initialising the mobile phone communication
// A user enters the phone number and phone alias on www.merchant.com.
 
try {
    // collect end-users phone number and alias from the web application
    String phoneNumber="collected from webSite";
    String phoneAlias="collected from webSite";
 
    String merchantReference=myFacade.generateMerchantReference("no_NO");
    // show the merchantReferanse to the end-user
    MobileInfo mobileInfo=new MobileInfo();
    mobileInfo.setAction("auth");
    mobileInfo.setMerchantReference(merchantReference);
    // URL must be the same hostname as the merchantConfig webAddresses configuration:
    mobileInfo.setUrl("https://www.merchant.com/BankID");
    //The expected sessionID during callbacks to the web application:
    mobileInfo.setSid("sessionID");
    mobileInfo.setPhoneNumber(phoneNumber);
    mobileInfo.setPhoneAlias(phoneAlias);
 
    // be aware that the following call can cause a hang for up to 3 minutes while the
    // end-user processes messages on the cell phone.At the same time the web application
    // must expect callbacks on the specified URL
    TransactionAndStatus ts=myFacade.requestMobileAction(mobileInfo);
 
} catch(BIDException be) {
    int errorCode=be.getErrorCode();
    String errorMessage=be.getMessage();
    String methodIdentifier=be.getMethodIdentifier();
}
 
 
// step 2: Handle initAuth callback from the mobile infrastructure
 
String operation=request.getParameter("operation");
String sid=request.getParameter("sid");
String encKey=request.getParameter("encKey");
String encData=request.getParameter("encData");
String encAuth=request.getParameter("encAuth");
 
BIDSessionData sessionData=new BIDSessionData();
 
try {
    String responseToClient=myFacade.initTransaction(operation,encKey,encData,encAuth,sid,sessionData);
    // store the sessionData in local session store for later use
} catch(BIDException be){
    int errorCode=be.getErrorCode();
    String errorMessage=be.getMessage();
    String methodIdentifier=be.getMethodIdentifier();
}
 
// step 3: Handle verifyAuth callback from the mobile infrastructure
 
String operation=request.getParameter("operation");
String sid=request.getParameter("sid");
String encKey=request.getParameter("encKey");
String encData=request.getParameter("encData");
String encAuth=request.getParameter("encAuth");
 
 
// get the sessionData from local session store
try {
    myFacade.verifyTransactionRequest(operation,encKey,encData,encAuth,sid,sessionData);
} catch (BIDException be) {
    int errorCode=be.getErrorCode();
    String errorMessage=be.getMessage();
    String methodIdentifier=be.getMethodIdentifier();
    if(errorCode==ErrorConstants.ERRCODE_BIDFACADE_VERIFY_TRANSACTION_REQ_FAILED_GETCERTSTATUS) {
        // Inform user that certificate is not valid
    }
// Handle the exception
}
 
// nextUrl required but ignored when BankID on mobile
sessionData.setNextURL("https://www.merchant.com/authenticated");
 
 
try {
    String responseToClient=myFacade.verifyTransactionReponse(sessionData);
    // return the response to the client, and update user session as authenticated
}catch(BIDException be){
    int errorCode=be.getErrorCode();
    String errorMessage=be.getMessage();
    String methodIdentifier=be.getMethodIdentifier();
    // Handle the exception
}

Authentication process - BankID Web-client 2.0

// BankID authentication. This example builds upon the earlier code excerpts using
 // "merchant"
 
 // step 1: Calling initSession to get the helper URI and the clientID
 
 // A user clicks on the login-button on www.merchant.com. The merchant-application
 // registers this action and sends an initSession to the BankID COI. In response the
 // merchant gets a link to the BankID helper and a clientID.
 //
  
 try {
  
     InitSessionInfo initSessionInfo = new InitSessionInfo();
     initSessionInfo.setAction("auth");
     initSessionInfo.setUserAgent("userHttpHeaderUserAgent");
     initSessionInfo.setMerchantURL("https://www.merchant.com/BankID");
     initSessionInfo.setLocaleId("nb");
     initSessionInfo.setSid("sid");
     initSessionInfo.setSuppressBroadcast("N");
     initSessionInfo.setCertType("ALL");
     initSessionInfo.setTimeout("40000");
     initSessionInfo.setNextURL("https://www.merchant.com/BankID");
     initSessionInfo.setMerchantFEDomain("merchantFEDomain");
     initSessionInfo.setWithCredentials("N");
      
      
     initSessionInfo = minFacade.initSession(initSessionInfo);
      
     // Return parameters of interest
     String clientID = initSessionInfo.getClientID();
     String helperURI = initSessionInfo.getHelperURI();
     String traceID = initSessionInfo.getTraceID();
      
     // store the traceID in local session store for later use
  
 } catch(BIDException be) {
    // Handle Error Situation
 }
 // Now redirect the user to a page where the helperURI javascript is sourced.
 // Call the init() function in the BankID helper javascript, to start the process of
 // retrieving the BankID Web-client.
  
 // step 2:
 // The BankID Web-client initialises and sends the following parameters to the merchant
 // application: operation, encKey, encData, encAuth and sid
  
 String operation = request.getParameter("operation");
 String sid = request.getParameter("sid");
 String encKey = request.getParameter("encKey");
 String encData = request.getParameter("encData");
 String encAuth = request.getParameter("encAuth");
  
 // Get the traceID from local session store
 String traceId = <the traceId from initSession>;
  
 // Create a BIDSessionData object to use during the whole authentication process.
 // Supply the traceID as input to the constructor.
 BIDSessionData sessionData = new BIDSessionData(traceId);
  
 try {
  
    String responseToClient = minFacade.initTransaction(operation, encKey, encData, encAuth, sid, sessionData);
    // store the sessionData in local session store for later use
 } catch(BIDException be) {
     String errorMessage = be.getMessage();
     int errorCode = be.getErrorCode();
     // Handle error situation
 }
  
 // step 3:
 // The end-user has signed the server challenge. The BankID Client returns the encKey, encData and encAuth to the merchant application
  
 String operation = request.getParameter("operation");
 String sid = request.getParameter("sid");
 String encKey = request.getParameter("encKey");
 String encData = request.getParameter("encData");
 String encAuth = request.getParameter("encAuth");
  
 // get the sessionData form local session store
 try {
    minFacade.verifyTransactionRequest(operation, encKey, encData, encAuth, sid, sessionData);
 } catch(BIDException be) {
     String errorMessage = be.getMessage();
     int errorCode = be.getErrorCode();
     // Handle error situation
 }
  
  
 // step 4:
 // The merchant application may want to get some information from the
 // end-user's certificate for authorization purposes or to connect the authenticated
 // user to e.g. a customer database.
  
 try {
     // Get the certificate information by passing the clientSignature String
     // recieved from the BIDSessionData object
     CertificateInfo certInfo = minFacade.getCertificateInfo(sessionData.getClientSignature());
     String issuerName = certInfo.getIssuerName();
     String subjectName = certInfo.getSubjectName();
     Date validFrom = certInfo.getValidFrom();
     Date validTo = certInfo.getValidTo();
     String versionNumber = certInfo.getVersionNumber();
     String serialNumber = certInfo.getSerialNumber();
     String keyAlgorithm = certInfo.getKeyAlgorithm();
     String keySize = certInfo.getKeySize();
     String policyOIDInfo = certInfo.getPolicyOID();
     String originator = certInfo.getOriginator();
     Date dateOfBirth = certInfo.getDateOfBirth();
     String bankName = certInfo.getBankName();
     String uniqueId = certInfo.getUniqueId();
     String commonName = certInfo.getCommonName();
     String emailAddress = certInfo.getEmailAddress();
     String isCertQualified = certInfo.isQualified();
     String monetaryLimitAmount = certInfo.getQcValueLimitAmount(); // Only if isQualified
     String monetaryLimitCurrency = certInfo.getQcValueLimitCurrency(); // Only if isQualified
 } catch(BIDException be) {
     String errorMessage = be.getMessage();
     int errorCode = be.getErrorCode();
     // Handle error situation
 }
  
RESPONSE TO THE BANKID CLIENT ***********************
return verifyTransactionResponse(sessionData);

Authentication process - BankID Web-client 2.1

 

// BankID authentication. This example builds upon the earlier code excerpts using
// "merchant"
 
// step 1: Calling initSession to get the helper URI and the clientID
 
// A user clicks on the login-button on www.merchant.com. The merchant-application
// registers this action and sends an initSession to the BankID COI. In response the
// merchant gets a link to the BankID helper and a clientID.
//
 
try {
    initSessionInfo initSessionInfo = new InitSessionInfo();
    initSessionInfo.setAction("auth");
    initSessionInfo.setUserAgent("userHttpHeaderUserAgent");
    initSessionInfo.setMerchantURL("https://www.merchant.com/BankID");
    initSessionInfo.setLocaleId("nb");
    initSessionInfo.setSid("sid");
    initSessionInfo.setSuppressBroadcast("N");
    initSessionInfo.setCertType("ALL");
    initSessionInfo.setTimeout("40000");
    initSessionInfo.setNextURL("https://www.merchant.com/BankID");
    initSessionInfo.setMerchantFEDomain("merchantFEDomain");
    initSessionInfo.setWithCredentials("N");
    initSessionInfo.setMerchantFEAncestors("domain1 domain2 ... domainN");
    initSessionInfo.setClientSessionTimeout("1800000");
    initSessionInfo.setClientVersion("2.1");
 
    initSessionInfo = minFacade.initSession(initSessionInfo);
 
    // Return parameters of interest
    String clientID = initSessionInfo.getClientID();
    String helperURI = initSessionInfo.getHelperURI();
    String traceID = initSessionInfo.getTraceID();
 
    // store the traceID in local session store for later use
 
} catch(BIDException be) {
    // Handle Error Situation
}
// Now redirect the user to a page where the helperURI javascript is sourced.
// Call the init() function in the BankID helper javascript, to start the process of
// retrieving the BankID Web-client.
 
// step 2:
// The BankID Web-client initialises and sends the following parameters to the merchant
// application: operation, encKey, encData, encAuth and sid
 
String operation = request.getParameter("operation");
String sid = request.getParameter("sid");
String encKey = request.getParameter("encKey");
String encData = request.getParameter("encData");
String encAuth = request.getParameter("encAuth");
 
// Get the traceID from local session store
String traceId = <the traceId from initSession>;
 
// Create a BIDSessionData object to use during the whole authentication process.
// Supply the traceID as input to the constructor.
BIDSessionData sessionData = new BIDSessionData(traceId);
 
try {
 
    String responseToClient = minFacade.initTransaction(operation, encKey, encData, encAuth, sid, sessionData);
    // store the sessionData in local session store for later use
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    int errorCode = be.getErrorCode();
    // Handle error situation
}
 
// step 3:
// The end-user has signed the server challenge. The BankID Client returns the encKey, encData and encAuth to the merchant application
 
String operation = request.getParameter("operation");
String sid = request.getParameter("sid");
String encKey = request.getParameter("encKey");
String encData = request.getParameter("encData");
String encAuth = request.getParameter("encAuth");
 
// get the sessionData form local session store
try {
    minFacade.verifyTransactionRequest(operation, encKey, encData, encAuth, sid, sessionData);
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    int errorCode = be.getErrorCode();
    // Handle error situation
}
 
 
// step 4:
// The merchant application may want to get some information from the
// end-user's certificate for authorization purposes or to connect the authenticated
// user to e.g. a customer database.
 
try {
    // Get the certificate information by passing the clientSignature String
    // recieved from the BIDSessionData object
    CertificateInfo certInfo = minFacade.getCertificateInfo(sessionData.getClientSignature());
    String issuerName = certInfo.getIssuerName();
    String subjectName = certInfo.getSubjectName();
    Date validFrom = certInfo.getValidFrom();
    Date validTo = certInfo.getValidTo();
    String versionNumber = certInfo.getVersionNumber();
    String serialNumber = certInfo.getSerialNumber();
    String keyAlgorithm = certInfo.getKeyAlgorithm();
    String keySize = certInfo.getKeySize();
    String policyOIDInfo = certInfo.getPolicyOID();
    String originator = certInfo.getOriginator();
    Date dateOfBirth = certInfo.getDateOfBirth();
    String bankName = certInfo.getBankName();
    String uniqueId = certInfo.getUniqueId();
    String commonName = certInfo.getCommonName();
    String emailAddress = certInfo.getEmailAddress();
    String isCertQualified = certInfo.isQualified();
    String monetaryLimitAmount = certInfo.getQcValueLimitAmount(); // Only if isQualified
    String monetaryLimitCurrency = certInfo.getQcValueLimitCurrency(); // Only if isQualified
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    int errorCode = be.getErrorCode();
    // Handle error situation
}
 
RESPONSE TO THE BANKID CLIENT ***********************
return verifyTransactionResponse(sessionData);

Signing process, no SEID SDO – BankID on Mobile

// Step 1,2 and 3 are the same as in the authentication process. Except that
// mobileInfo.setAction("sign") should be set instead of mobileInfo.setAction("auth")
 
// BankID Signing process without creating a SEID SDO (Signed Data Object)
// The BankID Client initiates the client-merchant dialogue by sending
// "operation=initSign"
 
// The end-user and the merchant agrees upon signing a contract.
String encKey = request.getParameter("encKey");
String encData = request.getParameter("encData");
String encAuth = request.getParameter("encAuth");
String operation = request.getParameter("operation");
String sid = request.getParameter("sid");
 
 
// create a BIDSessionData object to use during the whole signing process.
BIDSessionData sessionData = new BIDSessionData();
 
 
String contract = <read the contract from somewhere>;
sessionData.setDataToBeSigned(contract);
sessionData.setDataToBeSignedMimeType("plain/text");
sessionData.setDataDescription("Some description");
 
 
try {
    String response = minFacade.initTransaction(operation, encKey, encData, encAuth, sid, sessionData);
    // Store the sessionData object in locale session store for later use
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    int errorCode = be.getErrorCode();
    // Handle error situation
}
 
// The mobile device signs the data and returns its own signature. Verify the end user
// signature. The mobile infrastructure returns the following
// (operation=verifySign&encKey=<theEncKey>&encData=<theEncData>&encAuth=<theEncAuth>)
String encKey = request.getParameter("encKey");
String encData = request.getParameter("encData");
String encAuth = request.getParameter("encAuth");
String operation = request.getParameter("operation");
String sid = request.getParameter("sid");
 
// Get the sessionData from the locale session store
try {
    // The merchant must verify the end user signature.
    minFacade.verifyTransactionRequest(operation, encKey, encData, encAuth, sid, sessionData);
    return verifyTransactionResponse(sessionData);
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    int errorCode = be.getErrorCode();
    // Handle error situation
}

 

Signing process, no SEID SDO – BankID Web-client 2.0

 

// Step 1 is the same as in the authentication process. Except for some of the initSession
// parameters specific for the signing process.
 
initSessionInfo.setAction("sign");
initSessionInfo.setShowUnderstanding("Y");
initSessionInfo.setShowConfirmation("Y");
initSessionInfo.setDocDisplayMode("interior");
// set domain to load PDF if appropriate
initSessionInfo.setExtPDFDomain("www.merchant.com");
 
 
// BankID Signing process without creating a SEID SDO (Signed Data Object)
// The BankID Client initiates the client-merchant dialogue by sending
// "operation=initSign"
 
// step 2:
// The end-user and the merchant agrees upon signing a contract.
 
 
String encKey = request.getParameter("encKey");
String encData = request.getParameter("encData");
String encAuth = request.getParameter("encAuth");
String operation = request.getParameter("operation");
String sid = request.getParameter("sid");
 
 
// Get the traceID from local session store
String traceID = <the traceID from initSession>;
 
// create a BIDSessionData object to use during the whole signing process.
BIDSessionData sessionData = new BIDSessionData(traceID);
 
 
String contract = <read the contract from somewhere>;
sessionData.setDataToBeSigned(contract);
sessionData.setDataToBeSignedMimeType(<theMimeType>);
sessionData.setDataDescription("Some description");
 
// if signing a PDF, supply the url to load the PDF from as well
sessionData.setExtPDFUrl("
    https://www.mercant.com/pdf
");
 
 
try {
    String response = minFacade.initTransaction(operation, encKey, encData, encAuth, sid, sessionData);
    // Store the sessionData object in locale session store for later use
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    int errorCode = be.getErrorCode();
    // Handle error situation
}
 
// step 3:
// The client signs the data and returns its own signature. Verify the client
// signature. The client returns the following
// (operation=verifySign&encKey=<theEncKey>&encData=<theEncData>&encAuth=<theEncAuth>)
String encKey = request.getParameter("encKey");
String encData = request.getParameter("encData");
String encAuth = request.getParameter("encAuth");
String operation = request.getParameter("operation");
String sid = request.getParameter("sid");
 
// Get the sessionData from the locale session store
try {
    // The merchant must verify the client signature.
    minFacade.verifyTransactionRequest(operation, encKey, encData, encAuth, sid, sessionData);
    return verifyTransactionResponse(sessionData);
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    int errorCode = be.getErrorCode();
    // Handle error situation
}

Signing process, no SEID SDO – BankID Web-client 2.1

 

// Step 1 is the same as in the authentication process. Except for some of the initSession
// parameters specific for the signing process.
initSessionInfo.setAction(“sign”);
initSessionInfo.setShowUnderstanding(“Y”);
initSessionInfo.setShowConfirmation(“Y”);
initSessionInfo.setDocDisplayMode(“one of interior,window or overlay”);
// BankID Signing process without creating a SEID SDO (Signed Data Object)
// The BankID Client initiates the client-merchant dialogue by sending
// “operation=initSign”
// step 2:
// The end-user and the merchant agrees upon signing a contract.
 String encKey = request.getParameter(“encKey”);
 String encData = request.getParameter(“encData”);
 String encAuth = request.getParameter(“encAuth”);
 String operation = request.getParameter(“operation”);
 String sid = request.getParameter(“sid”);
 
// Get the traceID from local session store
 String traceID = ;
// create a BIDSessionData object to use during the whole signing process.
 BIDSessionData sessionData = new BIDSessionData(traceID);
  
// Add a text document
 sessionData.addTextDocument(“Text to sign”, "Test-data for signering");
// Add a PDF document
 sessionData.addTextDocument(<PDF bytes to sign>, "Test-data for signering");
// Add an XML document
 sessionData.addXMLDocument(“<XML to sign>”, “<XSL string>”, "Test-data for signering");
try {
    String response = minFacade.initTransaction(operation, encKey, encData, encAuth, sid, sessionData);
    // Store the sessionData object in locale session store for later use
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    int errorCode = be.getErrorCode();
    // Handle error situation
}
// step 3:
// The client signs the data and returns its own signature. Verify the client
// signature. The client returns the following
// (operation=verifySign&encKey=<the encKey>&encData=<the encData>&encAuth=<theEncAuth>)
String encKey = request.getParameter(“encKey”);
String encData = request.getParameter(“encData”);
String encAuth = request.getParameter(“encAuth”);
String operation = request.getParameter(“operation”);
String sid = request.getParameter(“sid”);
// Get the sessionData from the locale session store
try {
    // The merchant must verify the client signature.
    minFacade.verifyTransactionRequest(operation, encKey, encData, encAuth, sid, sessionData);
    return verifyTransactionResponse(sessionData);
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    int errorCode = be.getErrorCode();
    // Handle error situation
}

Signing process with SEID SDO, BankID Web-Client 2.0 and Mobile

The example in the code below is valid for all BankID clients except for the BankID Web-Client 2.1. The example is threrefore also valid for BankID on Mobile.

 

// BankID Signing process creating a SEID SDO (Signed Data Object)
// The BankID Client initiates the client-merchant dialogue by sending
// "operation=initSign"
 
// step 1:
// The end-user and the merchant agrees upon signing a contract.
 
 
String encKey = request.getParameter("encKey");
String encData = request.getParameter("encData");
String encAuth = request.getParameter("encAuth");
String operation = request.getParameter("operation");
String sid = request.getParameter("sid");
 
 
// create a BIDSessionData object to use during the whole signing process.
BIDSessionData sessionData = new BIDSessionData();
try {
    String contract = <read the contract from somewhere>;
    sessionData.setDataToBeSigned(contract);
    sessionData.setDataToBeSignedMimeType(<theMimeType>);
    sessionData.setDataDescription("The merchants description of the signed data");
 
    String response = minFacade.initTransaction(operation, encKey, encData, encAuth, sid, sessionData);
    //Store sessionData for later use
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    int errorCode = be.getErrorCode();
    // Handle error situation
}
 
// step 2:
// The client signs the data and returns its own signature. Verify the client
// signature. The client returns the following
// (operation=verifySign&encKey=<theEncKey>&encData=<theEncData>&encAuth=<theEncAuth>)
String encKey = request.getParameter("encKey");
String encData = request.getParameter("encData");
String encAuth = request.getParameter("encAuth");
String operation = request.getParameter("operation");
String sid = request.getParameter("sid");
 
// Get the sessionData from locale store
 
try {
    // The merchant must verify the client signature.
    minFacade.verifyTransactionRequest(operation, encKey, encData, encAuth, sid, sessionData);
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    int errorCode = be.getErrorCode();
    // Handle error situation
}
 
 
// step 3:
// Call createSDO
try {
    SEID_SDO seidSDO = minFacade.createSDO(
    sessionData. getClientSignatureBytes (),
    sessionData. getMerchantSignatureBytes (),
    sessionData. getSignedDataBytes (),
    sessionData. getDataToBeSignedMimeType(),
    sessionData. getMerchantOCSPBytes (),
    sessionData. getClientOCSPBytes (),
    sessionData.getDataDescription());
    sessionData.setSdo(seidSDO);
    // seidSDO.toXml() gives the result, UTF-8 encoded
    return verifyTransactionResponse(sessionData);
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    // Handle error situation
}

Signing process with SEID SDO with multiple signatures

 

// In this scenario we imagine that a merchant signs a document and makes several end-
// users sign it as well BEFORE creating a SEID_SDO
try {
    // For 1..N end-users the merchant initiates the signing process. Please refer to earlier
    // examples to see how that is done.
 
    // The merchant has received the end-user (client) PKCS#7. The merchant validates the
    // signature calling the verify(…) method and then gets the certificate status.The end-user
    // PKCS#7 and OCSPResponse (CertificateStatus) is stored in a PKCS7WithOCSPResponse instance
    // Do this for ALL end-users that are supposed to sign the "contract"
    CertificateStatus status = sessionData.getCertificateStatus();
 
    PKCS7WithOCSPResponse clientPKCS7AndOCSP = new PKCS7WithOCSPResponse();
    clientPKCS7AndOCSP.setB64OCSPResponse(status.getB64OCSPResponse());
    clientPKCS7AndOCSP.setB64PKCS7(b64ClientPKCS7);
    //…store the clientPKCS7AndOCSP for later processing
 
    // Now let's assume that the merchant has a PKCS7WithOCSPResponse[] with all
    // signatures.
    // The merchant must add its own signature as well (the merchant doesn't have to but in
    // this example it does.)
    // The merchant always have to sign the data first during a sign operation in BankID.
    // So we assume that the merchant signature (merchantPKCS#7) is available. The OCSP
    // for the merchant is alwys returned to the merchant application from the BankIDClient.
 
    PKCS7WithOCSPResponse merchantPKCS7AndOCSP = new PKCS7WithOCSPResponse();
    merchantPKCS7AndOCSP.setB64OCSPResponse(sessionData.getMerchantOCSP());
    merchantPKCS7AndOCSP.setB64PKCS7(sessionData.getMerchantSignature());
    // Add the merchantPKCS7AndOCSP (PKCS7WithOCSPResponse) to
    // PKCS7WithOCSPResponse[]allSignaturesAndOCSPs
 
    PKCS7WithOCSPResponse[]allSignaturesAndOCSPs = …; // Merchant and end-users signatures
 
    // Create a SEID_SDO holding ALL the signatures and OCSPReponses in the input
    // PKCS7WithOCSPResponse[]. The PKCS7WithOCSPResponse[] must have at least 1 entry
    SEID_SDO seidSDO = minFacade.createDynamicSDO (
        allSignaturesAndOCSPs,
        signedDataBytes,
        "text/plain" // OR "application/pdf" OR text/BIDXML
        "Multiple Signature SEID_SDO"
    );
 
    // The SEID_SDO result object is NOT Sealed. This means that the merchant application has
    // to call the createSDOSeal method when all parties have provided their signature
    // NOTE: "Sealing" a SEID_SDO means signing the content of the SEID_SDO. This also means
    // that the Seal-signature must also include the merchant CertificateStatus at the time
    // the SEID_SDO is sealed.
    CertificateStatus merchantCertStatusAtSealingTime = bidFacade.getOwnCertificateStatus();
    seidSDO = bidFacade.createSDOSeal( seidSDO,
        merchantCertStatusAtSealingTime.getB64OCSPResponse()
    );
 
    // Let's add the data to the SEID_SDO before storing it
    seidSDO.addSignedDataRaw(signedData);
 
    // Store the SEID_SDO to file for later use
    store2File("/SDO/sdo.sdo",seidSDO.toXML()); // NOTE: UTF-8 bytes of the SEID_SDO is stored
 
    // Let's assume that the merchant wants to to add a new client signature to the SEID_SDO
    // that is stored.
    byte[] utf8_SEID_SDO_XML_Bytes = readutf8File(("/SDO/sdo.sdo"));
 
    // We validate the dynamic SEID_SDO (multiple signature SEID_SDO), The inputs are
    // the SEID_SDO XML bytes (UTF-8), the signedData or NULL if the SEID_SDO already
    // has the data stored in it. The integer 0 telling that we do NOT expect any number of
    // signature. NOTE: If the integer is for example 4 then this method EXPECTS there to be
    // 4 signature in the SEID_SDO. Passing the 0 integer tells the method to ignore the
    // number of signature in the SEID_SDO (we do not expect any number). But keep in mind that
    // the SEID_SDO MUST contain at least 1 signature with its corresponding OCSP Response.
    // The Boolean "true" tells the method that the SEID_SDO is sealed. SO check the validity
    // of the Seal signature as well.
    bidFacade.validateDynamicSDO(utf8_SEID_SDO_XML_Bytes, signedData, 0, true);
 
    // SOME CONVIENIENCE METHODS / EXAMPLES
    // If you want to create a SEID_SDO instance then do the following
    SEID_SDO sdo = new SEID_SDO(utf8_SEID_SDO_XML_Bytes);
    // If you want to retrieve the signedData for other end-users to sign
    byte[] signedDataFromSDO =
        sdo.getSEID_SDOElement(0).getSignedObject().getSignedDataRaw()
    OR
    byte[] b64SignedDataFromSDO =
        sdo.getSEID_SDOElement(0).getSignedObject().getB64SignedData();
 
    // Precondition:
    // We already have a new client PKCS#7 and OCSP stored in a PKCS7WithOCSPResponse located
    // in a PKCS7WithOCSPResponse[]
    PKCS7WithOCSPResponse[] clientSignature2Add = …
 
    // NOTE: Adding new PKCS7WithOCSPResponse entries to the SEID_SDO invalidates the Seal
    // signature. This means that the resulting sdo does NOT contain the seal signature
    sdo = bidFacade.addSDOSignature(sdo, clientSignature2Add, signedDataFromSDO);
 
    // Seal the SEID_SDO
    CertificateStatus merchantCertStatusAtSealingTime = bidFacade.getOwnCertificateStatus();
    sdo = bidFacade.createSDOSeal(sdo,merchantCertStatusAtSealingTime.getB64OCSPResponse());
    store2File("/SDO/newsdo.sdo",sdo.toXML()); // NOTE: UTF-8 bytes of the SEID_SDO is stored
 
}
 catch(BIDException be) {
    String errorMessage = be.getMessage();
    // Handle error situation
}

Signing process with SEID SDO – BankID Web-client 2.1

 

// Step 1 is the same as in the authentication process. Except for some of the initSession
// parameters specific for the signing process.
initSessionInfo.setAction(“sign”);
initSessionInfo.setShowUnderstanding(“Y”);
initSessionInfo.setShowConfirmation(“Y”);
initSessionInfo.setDocDisplayMode(“one of interior,window or overlay”);
// BankID Signing process without creating a SEID SDO (Signed Data Object)
// The BankID Client initiates the client-merchant dialogue by sending
// “operation=initSign”
// step 2:
// The end-user and the merchant agrees upon signing a contract.
String encKey = request.getParameter(“encKey”);
String encData = request.getParameter(“encData”);
String encAuth = request.getParameter(“encAuth”);
String operation = request.getParameter(“operation”);
String sid = request.getParameter(“sid”);
  
// Get the traceID from local session store
String traceID = ;
// create a BIDSessionData object to use during the whole signing process.
BIDSessionData sessionData = new BIDSessionData(traceID);
   
// Add a text document
sessionData.addTextDocument(“Text to sign”, "Test-data for signering");
// Add a PDF document
sessionData.addTextDocument(<PDF bytes to sign>, "Test-data for signering");
// Add an XML document
sessionData.addXMLDocument(“<XML to sign>”, “<XSL string>”, "Test-data for signering");
try {
    String response = minFacade.initTransaction(operation, encKey, encData, encAuth, sid, sessionData);
    // Store the sessionData object in locale session store for later use
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    int errorCode = be.getErrorCode();
    // Handle error situation
}
// step 3:
// The client signs the data and returns its own signature. Verify the client
// signature. The client returns the following
// (operation=verifySign&encKey=<the encKey>&encData=<the encData>&encAuth=<theEncAuth>)
String encKey = request.getParameter(“encKey”);
String encData = request.getParameter(“encData”);
String encAuth = request.getParameter(“encAuth”);
String operation = request.getParameter(“operation”);
String sid = request.getParameter(“sid”);
// Get the sessionData from the locale session store
try {
    // The merchant must verify the client signature.
    minFacade.verifyTransactionRequest(operation, encKey, encData, encAuth, sid, sessionData);
    // Create SDO(s)
    List<SEID_SDO> sdoList = new ArrayList<>();
    for (DocumentToSign doc : sessionData.getDocuments()) {
        SEID_SDO seidSDO = bidFacade.createSDO(
        doc.getClientSignatureBytes(),
        doc.getMerchantSignatureBytes(),
        doc.getSignedDataBytes(),
        doc.getMimeTypeValue(),
        sessionData.getMerchantOCSPBytes(),
        doc.getClientOCSPBytes(),
        doc.getDescription());
        sdoList.add(seidSDO); // seidSDO.toXml() gives the result, UTF-8 encoded
    }
    return verifyTransactionResponse(sessionData);
} catch(BIDException be) {
    String errorMessage = be.getMessage();
    int errorCode = be.getErrorCode();
    // Handle error situation
}

Signing process and creation of PDF signature (PAdES) - BankID Web-client 2.0

 

// Step 1 is the same as in the authentication process. Except for some of the initSession
// parameters specific for the signing process.

initSessionInfo.setAction(“sign”);
initSessionInfo.setShowUnderstanding(“Y”);
initSessionInfo.setShowConfirmation(“Y”);
initSessionInfo.setDocDisplayMode(“interior”);

// BankID Signing process and creation of PDF signature (PAdES)
// The BankID Client initiates the client-merchant dialogue by sending
// “operation=initSign”

// step 2:
// The end-user and the merchant agrees upon signing a contract.

String encKey = request.getParameter(“encKey”);
String encData = request.getParameter(“encData”);
String encAuth = request.getParameter(“encAuth”);
String operation = request.getParameter(“operation”);
String sid = request.getParameter(“sid”);

// Get the traceID from local session store
String traceID = <the traceID from initSession>;

// create a BIDSessionData object to use during the whole signing process.
BIDSessionData sessionData = new BIDSessionData(traceID);

// Add a PDF document to be signed. The PDF document must contain an empty PDF Signature Dictionary.
sessionData.setDataToBeSigned((<PDFbytes to sign>);
sessionData.setDataToBeSignedMimeType(<theMimeType>);
sessionData.setDataDescription(“Some description”);
sessionData.setExtPDFUrl(“https://www.mercant.com/pdf”);


// Configure use of OCSP and CMS formats compatible with PAdES signatures
sessionData.setOcspFormat(OCSPFormat.OCSP_RFC6960_COMPATIBLE);
sessionData.setCmsFormat(CMSFormat.PKCS7_ISO320001);

try {
	String response = minFacade.initTransaction(operation, encKey, encData, encAuth, sid, sessionData);
	// Store the sessionData object in locale session store for later use   

} catch(BIDException be) {
	String errorMessage = be.getMessage();
	int errorCode = be.getErrorCode();
	// Handle error situation
}

// step 3:
// The client signs the data and returns its own signature. Verify the client
// signature. The client returns the following
// (operation=verifySign&encKey=<theEncKey>&encData=<theEncData>&encAuth=<theEncAuth>)

String encKey = request.getParameter(“encKey”);
String encData = request.getParameter(“encData”);
String encAuth = request.getParameter(“encAuth”);
String operation = request.getParameter(“operation”);
String sid = request.getParameter(“sid”);

// Get the sessionData from the locale session store  
try {
	// The merchant must verify the client signature.
	minFacade.verifyTransactionRequest(operation, encKey, encData, encAuth, sid, sessionData);

	// Extract content for the PDF Signature
	byte[] clientSignature = sessionData.getClientSignatureBytes();
	byte[] clientBasicOCSPResponse = sessionData.getCertificateStatus().getB64OCSPResponse();
	byte[] clientFullOCSPResponse = sessionData.getCertificateStatus().getFullOCSPResponse();
 
	// Add the contents above to the PDF Signature. Use clientBasicOCSPResponse or
	// clientFullOCSPResponse according to what is expected as input by the chosen PDF library
 
	return verifyTransactionResponse(sessionData);
} catch(BIDException be) {
	String errorMessage = be.getMessage();
	int errorCode = be.getErrorCode();
	// Handle error situation
}

Signing process and creation of PDF signature (PAdES) - BankID Web-client 2.1

 

// Step 1 is the same as in the authentication process. Except for some of the initSession
// parameters specific for the signing process.

initSessionInfo.setAction(“sign”);
initSessionInfo.setShowUnderstanding(“Y”);
initSessionInfo.setShowConfirmation(“Y”);
initSessionInfo.setDocDisplayMode(“interior|window|overlay”);

// BankID Signing process and creation of PDF signature (PAdES)
// The BankID Client initiates the client-merchant dialogue by sending
// “operation=initSign”

// step 2:
// The end-user and the merchant agrees upon signing a contract.
 
String encKey = request.getParameter(“encKey”);
String encData = request.getParameter(“encData”);
String encAuth = request.getParameter(“encAuth”);
String operation = request.getParameter(“operation”);
String sid = request.getParameter(“sid”);

// Get the traceID from local session store
String traceID = <the traceID from initSession>;

// create a BIDSessionData object to use during the whole signing process.
BIDSessionData sessionData = new BIDSessionData(traceID);

// Add a PDF document to be signed. The PDF document must contain an empty PDF Signature Dictionary.
sessionData.addPDFDocument(<PDF bytes to sign>, "Test-data for signering");

// Configure use of OCSP and CMS formats compatible with PAdES signatures
sessionData.setOcspFormat(OCSPFormat.OCSP_RFC6960_COMPATIBLE); 
sessionData.setCmsFormat(CMSFormat.PKCS7_ISO320001);
 
try {
	String response = minFacade.initTransaction(operation, encKey, encData, encAuth, sid, sessionData);
	// Store the sessionData object in locale session store for later use
} catch(BIDException be) {
	String errorMessage = be.getMessage();
	int errorCode = be.getErrorCode();
	// Handle error situation
}
 
// step 3:
// The client signs the data and returns its own signature. Verify the client
// signature. The client returns the following
// (operation=verifySign&encKey=<theEncKey>&encData=<theEncData>&encAuth=<theEncAuth>)
String encKey = request.getParameter(“encKey”);
String encData = request.getParameter(“encData”);
String encAuth = request.getParameter(“encAuth”);
String operation = request.getParameter(“operation”);
String sid = request.getParameter(“sid”);

// Get the sessionData from the locale session store
try {
	// The merchant must verify the client signature.
	minFacade.verifyTransactionRequest(operation, encKey, encData, encAuth, sid, sessionData);

	//Add PDF Signature elements to the document(s)
	for(DocumentToSign doc : sessionData.getDocuments()) {
		if(doc.getMimeType().equals(MIMEType.PDF)) {
			// Extract content for the PDF Signature
			byte[] clientSignature = doc.getClientSignatureBytes();
			byte[] clientBasicOCSPResponse = doc.getCertificateStatus().getB64OCSPResponse();
			byte[] clientFullOCSPResponse = doc.getCertificateStatus().getFullOCSPResponse();
 
			// Add the contents above to the PDF Signature. Use clientBasicOCSPResponse or
			// clientFullOCSPResponse according to what is expected as input by the chosen PDF
			// library
		}
	}
 
	return verifyTransactionResponse(sessionData);
} catch(BIDException be) {
	String errorMessage = be.getMessage();
	int errorCode = be.getErrorCode();
	// Handle error situation
}

Retrieve additional information from VA

A call to verifyTransactionRequest includes a call to VA to get the client certificate status. The CertificateStatus object can be retrieved by calling sessionData.getCertificateStatus() after a call to verifyTransactionRequest.

The code below shows an example of how to get the status of a certificate and at the same time retrieve additional information (AI) about the certificate holder.

 

//If additional information is wanted about the client, and an agreement to obtain
//such information exists with the bank, the following infoitems may also be requested:
ArrayList additionalInfos = new ArrayList();
 
//To retrieve the account number of the client, if it exists
additionalInfos.add(JServerConstants.LABEL_OID_OCSP_ACCOUNT);
 
//To retrieve the social security number of the client, if it exists
additionalInfos.add(JServerConstants.LABEL_OID_OCSP_SSN);
 
//To retrieve the org.number of the client, if the client is a merchant and it exists
additionalInfos.add(JServerConstants.LABEL_OID_OCSP_ORGNO);
 
sessionData.setAdditionalInfoList(additionalInfos);
 
bankIDFacade.verifyTransactionRequest(operation, encKey, encData, encAuth, sid, sessionData);
//End-user is now successfully authenticated
// If the infoitems for AI (additional information) from the VA is set, the following
// will be available at the CertificateStatus object:
CertificateStatus certStatus = sessionData.getCertificateStatus();
if(certStatus.getAddInfoSSNErr() != null)
   System.out.println("User's SSN not found: " + certStatus.getAddInfoSSNErr());
else
   System.out.println("Found the user's SSN: " + certStatus.getAddInfoSSN());
 
// For multiple document signing
AdditionalInformation ai = sessionData.getAdditionalInformation();
if(ai.getAddInfoSSNErr() != null)
   System.out.println("User's SSN not found: " + ai.getAddInfoSSNErr());
else
   System.out.println("Found the user's SSN: " + ai.getAddInfoSSN());

 

Since the verifyTransactionRequest method includes a check of the client certificate status, the getCertificateStatus method is not necessary to call explisitly.

For multiple document signing the request for AI will be sent for the first document only. As described in the example above, the AI will be accessible to the merchant in the AdditionalInformation object in BidSessionData. The same information can also be found in the CertificateStatus of the first document in the document list.