-
Notifications
You must be signed in to change notification settings - Fork 18
Examples of using it
Here are examples of authenticating and creating signature with Smart-ID Java client
// Client setup. Note that these values are demo environment specific.
SmartIdClient client = new SmartIdClient();
client.setRelyingPartyUUID("00000000-0000-0000-0000-000000000000");
client.setRelyingPartyName("DEMO");
client.setHostUrl("https://sid.demo.sk.ee/smart-id-rp/v1/");
The production environment host URL, relying party UUID and name are fixed in the Smart-ID service agreement.
// consists of country and personal identity code
NationalIdentity nationalIdentity = new NationalIdentity("EE", "10101010005");
// For security reasons a new hash value must be created for each new authentication request
AuthenticationHash authenticationHash = AuthenticationHash.generateRandomHash();
String verificationCode = authenticationHash.calculateVerificationCode();
SmartIdAuthenticationResponse authenticationResponse = client
.createAuthentication()
.withNationalIdentity(nationalIdentity)
.withAuthenticationHash(authenticationHash)
.withCertificateLevel("QUALIFIED") // Certificate level can either be "QUALIFIED" or "ADVANCED"
.authenticate();
Note that
verificationCode
should be displayed on the web page or some sort of web service, so the person signing through the Smart-ID mobile app can verify if the verification code displayed on the phone matches with the one shown on the web page.
In addition to national identity there is also possibilty to authenticate with document number:
String documentNumber = "PNOEE-10101010005-Z1B2-Q";
AuthenticationHash authenticationHash = AuthenticationHash.generateRandomHash();
String verificationCode = authenticationHash.calculateVerificationCode();
SmartIdAuthenticationResponse authenticationResponse = client
.createAuthentication()
.withDocumentNumber(documentNumber)
.withAuthenticationHash(authenticationHash)
.withCertificateLevel("QUALIFIED")
.authenticate();
AuthenticationResponseValidator authenticationResponseValidator = new AuthenticationResponseValidator();
SmartIdAuthenticationResult authenticationResult = authenticationResponseValidator.validate(authenticationResponse);
// authentication validity result
boolean isValid = authenticationResult.isValid();
// When the result is not valid then the reason(s) for invalidity are obtainable like this:
List <String> errors = authenticationResult.getErrors();
When the authentication result is valid a session can now be created within the e-service or application. As the session logic is dependant on the implementation and may vary from system to system, so this is something integrator has to do itself. AuthenticationIdentity
can be helpful for obtaining information about the authenticated person when constructing the session.
AuthenticationIdentity authIdentity = authenticationResult.getAuthenticationIdentity();
String givenName = authIdentity.getGivenName(); // e.g. Mari-Liis"
String surName = authIdentity.getSurName(); // e.g. "Männik"
String identityCode = authIdentity.getIdentityCode(); // e.g. "47101010033"
String country = authIdentity.getCountry(); // e.g. "EE"
Note that the certificate choosing process (before the actual singing) is necessary for the AdES-style digital signatures which require knowledge of the certificate beforehand.
- Initiate certificate choice between multiple signing certificates the user may hold on his/her different mobile devices.
SmartIdClient client = new SmartIdClient();
client.setRelyingPartyUUID("00000000-0000-0000-0000-000000000000");
client.setRelyingPartyName("DEMO");
client.setHostUrl("https://sid.demo.sk.ee/smart-id-rp/v1/");
NationalIdentity nationalIdentity = new NationalIdentity("EE", "10101010005");
SmartIdCertificate certificateResponse = client
.getCertificate()
.withNationalIdentity(nationalIdentity)
.withCertificateLevel("QUALIFIED")
.fetch();
X509Certificate signersCertificate = certificateResponse.getCertificate() // get the signer's certificate
String documentNumber = certificateResponse.getDocumentNumber();
- Create the signature with the chosen certificate.
SignableHash hashToSign = new SignableHash();
hashToSign.setHashType(HashType.SHA256);
hashToSign.setHashInBase64("0nbgC2fVdLVQFZJdBbmG7oPoElpCYsQMtrY0c0wKYRg=");;
// to display the verification code
String verificationCode = hashToSign.calculateVerificationCode();
SmartIdSignature smartIdSignature = client
.createSignature()
.withDocumentNumber(documentNumber)
.withSignableHash(hashToSign)
.withCertificateLevel("QUALIFIED")
.sign();
byte[] signature = smartIdSignature.getValue();
SignableHash hashToSign = new SignableHash();
hashToSign.setHashType(HashType.SHA256);
hashToSign.setHashInBase64("0nbgC2fVdLVQFZJdBbmG7oPoElpCYsQMtrY0c0wKYRg=");
String verificationCode = hashToSign.calculateVerificationCode();
SmartIdSignature smartIdSignature = client
.createSignature()
.withDocumentNumber(documentNumber)
.withSignableHash(hashToSign)
.withCertificateLevel("QUALIFIED") // Certificate level can either be "QUALIFIED" or "ADVANCED"
.sign();
byte[] signature = smartIdSignature.getValue();
Note that
verificationCode
should be displayed on the web page or some sort of web service.
This is good case when we have some data that we want to sign, but it isn't transformed into a hash yet.
We can use SignableData
, provide it with the wanted hash algorithm and the client will deal with hashing for you.
SignableData dataToSign = new SignableData("Some raw data to sign".getBytes());
dataToSign.setHashType(HashType.SHA256);
String verificationCode = dataToSign.calculateVerificationCode();
SmartIdSignature smartIdSignature = client
.createSignature()
.withDocumentNumber(documentNumber)
.withSignableData(dataToSign)
.withCertificateLevel("QUALIFIED")
.sign();
byte[] signature = smartIdSignature.getValue();
Under the hood each operation (authentication, choosing certificate and signing) consist of 2 request steps:
- Initiation request
- Session status request
Session status request by default is a long poll method, meaning the request method might not return until a timeout expires. Caller can tune each poll's timeout value in milliseconds inside the bounds set by service operator to turn it into a short poll.
Example:
SmartIdClient client = new SmartIdClient();
// ...
client.setSessionStatusResponseSocketOpenTime(TimeUnit.SECONDS, 5L); // sets the timeout for each session status poll
client.setPollingSleepTimeout(TimeUnit.SECONDS, 1L) // sets the pause between each session status poll
As Smart-ID Java client uses Jersey client for network communication underneath, we've exposed Jersey API for network connection configuration.
Here's an example how to configure HTTP connector's custom socket timeouts for the Smart-ID client:
SmartIdClient client = new SmartIdClient();
// ...
ClientConfig clientConfig = new ClientConfig();
clientConfig.property(ClientProperties.CONNECT_TIMEOUT, 5000);
clientConfig.property(ClientProperties.READ_TIMEOUT, 30000);
client.setNetworkConnectionConfig(clientConfig);
And here's an example how to use Apache Http Client with custom socket timeouts as the HTTP connector instead of the default HttpUrlConnection
:
SmartIdClient client = new SmartIdClient();
// ...
ClientConfig clientConfig = new ClientConfig().connectorProvider(new ApacheConnectorProvider());
RequestConfig reqConfig = RequestConfig.custom()
.setConnectTimeout(5000)
.setSocketTimeout(30000)
.setConnectionRequestTimeout(5000)
.build();
clientConfig.property(ApacheClientProperties.REQUEST_CONFIG, reqConfig);
client.setNetworkConnectionConfig(clientConfig);
Keep in mind that the HTTP connector timeout of waiting for data shouldn't normally be less than the timeout for session status poll.
ResteasyClient client = new ResteasyClientBuilder()
.sslContext(SmartIdClient.createSslContext(Arrays.asList("pem cert 1", "pem cert 2")))
.build();
SmartIdClient client = new SmartIdClient();
client.setRelyingPartyUUID("00000000-0000-0000-0000-000000000000");
client.setRelyingPartyName("DEMO");
client.setConfiguredClient(client);
client.setHostUrl("https://sid.demo.sk.ee/smart-id-rp/v1/");
ResteasyClient client = new ResteasyClientBuilder()
.defaultProxy("localhost", 8080, "http")
.build();
SmartIdClient client = new SmartIdClient();
client.setRelyingPartyUUID("00000000-0000-0000-0000-000000000000");
client.setRelyingPartyName("DEMO");
client.setConfiguredClient(client);
client.setHostUrl("https://sid.demo.sk.ee/smart-id-rp/v1/");