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
let crypto = require("crypto");
let timestamp = new Date().toISOString();
let api_key = "<Your Signature API Key>";
let partner_id = "<Your partner id>";
let hmac = crypto.createHmac("sha256", api_key);
hmac.update(timestamp, "utf8");
hmac.update(partner_id, "utf8");
hmac.update("sid_request", "utf8");
let signature = hmac.digest().toString("base64");
String apiKey = "<Your Signature API Key>";
String partnerId = "<Your partner id>";
Long timestamp = System.currentTimeMillis();
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(apiKey.getBytes(), "HmacSHA256"));
mac.update(new SimpleDateFormat(DATE_TIME_FORMAT).format(timestamp).getBytes(StandardCharsets.UTF_8));
mac.update(partnerId.getBytes(StandardCharsets.UTF_8));
mac.update("sid_request".getBytes(StandardCharsets.UTF_8));
String signature = Base64.getEncoder().encodeToString(mac.doFinal());
using System;
using System.Security.Cryptography;
using System.Text;
namespace csharp_sample
{
class Program
{
static void Main(string[] args)
{
string timeStamp = DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss.fffK", System.Globalization.CultureInfo.InvariantCulture);
string apiKey = "513205c6-c420-44e5-ab85-370986dc3f19";
string partnerID = "1622";
string data = timeStamp + partnerID + "sid_request";
UTF8Encoding utf8 = new UTF8Encoding();
Byte[] key = utf8.GetBytes(apiKey);
Byte[] message = utf8.GetBytes(data);
HMACSHA256 hash = new HMACSHA256(key);
var signature = hash.ComputeHash(message);
Console.WriteLine("Signature: " + Convert.ToBase64String(signature));
Console.WriteLine("TimeStamp: " + timeStamp);
}
}
}
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 response
received_signature = ""
# The actual timestamp received in the callback response
received_timestamp = ""
# Your partner ID
partner_id = ""
# Your api key for the environment in concern (sandbox / production)
api_key = ""
# Function to verify the signature
def confirm_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_signature
end
# print out a confirmation status
is_signature_valid = confirm_signature(received_signature, received_timestamp, partner_id, api_key)
puts "Is the signature valid? #{is_signature_valid}"
const crypto = require("crypto");
// Inputs received along with the request
let received_signature = ""; // The signature received in the callback response
let received_timestamp = ""; // The actual timestamp received in the callback response
let partner_id = ""; // Your partner ID
let api_key = ""; // Your api key for the environment in concern (sandbox / production)
function confirmSignature(
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 data
let generated_signature = hmac.digest().toString("base64");
// Compare the generated signature with the received signature
return generated_signature === received_signature;
}
const is_signature_valid = confirmSignature(
received_signature,
received_timestamp,
partner_id,
api_key,
);
console.log(`Is the signature valid? ${is_signature_valid}`);
import base64
import hashlib
import hmac
# The signature received in the callback response
received_signature = ""
# The actual timestamp received in the callback response
received_timestamp = ""
# Your partner ID
partner_id = ""
# Your api key for the environment in concern (sandbox / production)
api_key = ""
def confirm_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 one
return hmac.compare_digest(received_signature, generated_signature)
# print out a confirmation status
is_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)
function confirmSignature(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 response
return ($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;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class ConfirmSignature {
public static void main(String[] args) {
String receivedSignature = ""; // The signature received in the callback response
String receivedTimestamp = ""; // The actual timestamp received in the callback response
String partnerId = ""; // Your partner ID
String 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);
}
public static boolean confirmSignature(String receivedSignature, String receivedTimestamp, String partnerId,
String apiKey) {
try {
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(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 data
String generatedSignature = Base64.getEncoder().encodeToString(mac.doFinal());
// Compare the generated signature with the received signature
return generatedSignature.equals(receivedSignature);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
using System;
using System.Security.Cryptography;
using System.Text;
using System.Linq;
public static bool confirmSignature(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 with
bool err = false;
string data = receivedTimestamp + partnerID + "sid_request";
UTF8Encoding utf8 = new UTF8Encoding();
Byte[] key = utf8.GetBytes(apiKey);
Byte[] message = utf8.GetBytes(data);
HMACSHA256 hash = new HMACSHA256(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.