If you use one of the supplied SDKs, there is no reason to use the code in the following section as the signature can be generated by calling the generate_signature function.
The generated signature has to be passed as a string in your request.
Overview
To communicate with our system we require a signature on each request to ensure that both parties are who they say they are. To calculate your signature, you will need your partner ID and API Key for Signature, both of which are available on the portal.
API Key for Signature
You can find and generate your an API key here. The key is unique to each environment, so you will need a different key for the sandbox and production environments. You can rotate your API key any time, however your previous key will be immediately disabled.
Partner ID
You will need to know your partner ID, to create the signature. Your partner ID can be viewed when logged into the portal. To calculate your signature you will need to input your partner ID as a string, as explained below
Reminder: You must pass the signature as a string in your request.
Your timestamp should be a string in the ISO format "yyyy-MM-dd'T'HH:mm:ss.fffK"
Confirming an incoming signature
To verify the authenticity of the response received from your callback as genuinely originating from Smile ID, you can confirm the returned signature and timestamp. The sample codes provided below can be used to confirm the signature in the request:
Example code for confirming the signature
require'openssl'require'time'require'base64'# Example inputs - replace these with actual received values# The signature received in the callback responsereceived_signature =""# The actual timestamp received in the callback responsereceived_timestamp =""# Your partner IDpartner_id =""# Your api key for the environment in concern (sandbox / production)api_key =""# Function to verify the signaturedefconfirm_signature(received_signature, received_timestamp, partner_id, api_key) hmac =OpenSSL::HMAC.new(api_key,'sha256') hmac.update(received_timestamp) hmac.update(partner_id) hmac.update("sid_request") generated_signature =Base64.strict_encode64(hmac.digest) received_signature == generated_signatureend# print out a confirmation statusis_signature_valid = confirm_signature(received_signature, received_timestamp, partner_id, api_key)puts"Is the signature valid? #{is_signature_valid}"
constcrypto=require("crypto");// Inputs received along with the requestlet received_signature =""; // The signature received in the callback responselet received_timestamp =""; // The actual timestamp received in the callback responselet partner_id =""; // Your partner IDlet api_key =""; // Your api key for the environment in concern (sandbox / production)functionconfirmSignature( received_signature, received_timestamp, partner_id, api_key,) {let hmac =crypto.createHmac("sha256", api_key);hmac.update(received_timestamp,"utf8");hmac.update(partner_id,"utf8");hmac.update("sid_request","utf8");// Generate the signature based on received datalet generated_signature =hmac.digest().toString("base64");// Compare the generated signature with the received signaturereturn generated_signature === received_signature;}constis_signature_valid=confirmSignature( received_signature, received_timestamp, partner_id, api_key,);console.log(`Is the signature valid? ${is_signature_valid}`);
import base64import hashlibimport hmac# The signature received in the callback responsereceived_signature =""# The actual timestamp received in the callback responsereceived_timestamp =""# Your partner IDpartner_id =""# Your api key for the environment in concern (sandbox / production)api_key =""defconfirm_signature(received_signature,received_timestamp,partner_id,api_key):# Recreate the HMAC object with the same parameters hmac_new = hmac.new(api_key.encode("utf-8"), digestmod=hashlib.sha256) hmac_new.update(received_timestamp.encode("utf-8")) hmac_new.update(str(partner_id).encode("utf-8")) hmac_new.update("sid_request".encode("utf-8"))# Generate the signature again generated_signature = base64.b64encode(hmac_new.digest()).decode("utf-8")# Compare the provided signature with the generated onereturn hmac.compare_digest(received_signature, generated_signature)# print out a confirmation statusis_signature_valid =confirm_signature(received_signature, received_timestamp, partner_id, api_key)print(f"Is the signature valid? {is_signature_valid}")
<?php// Assume these values are received with the request$receivedSignature =""; // The signature received in the callback response$receivedTimestamp =""; // The actual timestamp received in the callback response$partnerId =""; // Your partner ID$apiKey =""; // Your api key for the environment in concern (sandbox / production)functionconfirmSignature(string $receivedSignature,string $receivedTimestamp,String $partnerId,string $apiKey):bool{// Concatenate the received data to form the message $message = $receivedTimestamp . $partnerId ."sid_request";// Generate the HMAC hash of the message $generatedSignature =base64_encode(hash_hmac('sha256', $message, $apiKey,true));// Compare the received signature with the generated signature and return boolean responsereturn ($generatedSignature === $receivedSignature);}//print out a confirmation status$is_signature_valid =confirmSignature($receivedSignature, $receivedTimestamp, $partnerId, $apiKey)?'True':'False';echo"Is the signature valid? ".$is_signature_valid;
importjavax.crypto.Mac;importjavax.crypto.spec.SecretKeySpec;importjava.nio.charset.StandardCharsets;importjava.util.Base64;publicclassConfirmSignature {publicstaticvoidmain(String[] args) {String receivedSignature =""; // The signature received in the callback responseString receivedTimestamp =""; // The actual timestamp received in the callback responseString partnerId =""; // Your partner IDString apiKey =""; // Your api key for the environment in concern (sandbox / production)Boolean isSignatureValid =confirmSignature(receivedSignature, receivedTimestamp, partnerId, apiKey);System.out.println("Is the signature valid? "+ isSignatureValid); }publicstaticbooleanconfirmSignature(String receivedSignature,String receivedTimestamp,String partnerId,String apiKey) {try {Mac mac =Mac.getInstance("HmacSHA256");mac.init(newSecretKeySpec(apiKey.getBytes(),"HmacSHA256"));mac.update(receivedTimestamp.getBytes(StandardCharsets.UTF_8));mac.update(partnerId.getBytes(StandardCharsets.UTF_8));mac.update("sid_request".getBytes(StandardCharsets.UTF_8));// Generate the signature based on received dataString generatedSignature =Base64.getEncoder().encodeToString(mac.doFinal());// Compare the generated signature with the received signaturereturngeneratedSignature.equals(receivedSignature); } catch (Exception e) {e.printStackTrace();returnfalse; } }}
usingSystem;usingSystem.Security.Cryptography;usingSystem.Text;usingSystem.Linq;publicstaticboolconfirmSignature(string receivedSignature,string receivedTimestamp,string partnerID,string apiKey){ // Use the signature and timestamp from the response sent to you via the webhook // This method returns true if the signature is fine and has not been tampered withbool err =false;string data = receivedTimestamp + partnerID +"sid_request";UTF8Encoding utf8 =newUTF8Encoding();Byte[] key =utf8.GetBytes(apiKey);Byte[] message =utf8.GetBytes(data);HMACSHA256 hash =newHMACSHA256(key);var generatedSignature =hash.ComputeHash(message);byte[] oldSignature =System.Convert.FromBase64String(receivedSignature); err =!oldSignature.SequenceEqual(generatedSignature);return!err;}
Reminder: You must pass the received signature, received timestamp, partner id and api key as strings.