Revision History
SI# | Ver# | Modified By | Update | Updated On |
---|---|---|---|---|
1 | 3.4.3 | Tech Team | - Initial Version | 23/05/2019 |
1. Introduction
Authentication is the process of verifying the Identity of a User. Businesses always have to authenticate the identity of a user before providing him access to their application or products/services.
Authentication happens in the form of :
What you Know - User Name, Password, Knowledge-based questions, etc.
What you Have - OTP, device ID, etc.
What you Are - Biometrics - Fingerprint, Voice, Face etc.
Khoslalabs FaceAuth SDK provides the option of :
- Authenticating a user by using Face Plus Liveness as Biometrics. or
- Enrolling a user using Face + Liveness
2. Solution Options
Khoslalab’s Face Auth Solution can be seamlessly integrated with client’s business application to authenticate user using Face with Liveness as biometric or to enroll a user with face liveness as Biometric.
FaceAuth Solution offers the following options :
- FaceAuth : Enrollment SDK
FaceAuth SDK can be used for the purpose of enrolling a user that can be integrated with clients business application. This can be used in user Onboarding Flow, where the liveness of the user can be ensured and face image of the user can be captured.
- FaceAuth : Login SDK
FaceAuth SDK can be used for the purpose of Login/Authentication of a user, where in SDK can be integrated with clients business application. This can be used in user Authentication Flow, where the liveness of the user can be ensured and face image of the user can be captured for Authentication process.
- FaceAuth : Enrollment API
Enrollment API can be used to capture an image and store in Veri5Digital Platform. FaceAuth-Login SDK then will capture the live user for authentication purpose and use this registered image as the reference data for comparison.
FaceAuth SDK Solution can be used in the following combination of different flavors:
ENROLLMENT/REGISTRATION | LOGIN/AUTH |
---|---|
SDK | SDK |
API | SDK |
2.1 FaceAuth - Enrollment SDK
Enrollment SDK can be integrated with clients business application and provides the following capabilities :
Capability to capture Live Face and do enrollment. SDK will return the captured image post completion. Liveness determination is the key feature.
Along with the liveness feature, SDK does enrollment in either of the following two modes
- Capture live face image and register it against a user id passed by the calling business application.
- Return the captured face post deciding the liveness.
2.2 FaceAuth - Login/Auth SDK
Login SDK can be integrated with clients business application and provides the following capabilities :
Capability to capture Live Face and do authentication. Liveness determination is the key feature.
SDK performs authentication using either of the following modes :
- Accepts face image of the user passed by calling business application and compare with the captured live face.
- Compare captured live face with already enrolled face of the user.
2.3 FaceAuth - Enrollment API
Enrollment API is used to register a user with a unique user id passed by the client and the user face image against which authentication will be performed when user trying to login.
3. How to Integrate FaceAuth SDK
This section explains the steps to integrate KL’s FaceAuth SDK with client’s hosting application.FaceAuth SDK can perform as Enrollment SDK or Login/Authentication SDK.
Khosla Lab offers clients following environments :
Sandbox Environment : Its recommended for the clients to integrate their application with SDK in Sandbox Environment and do the testing and get it certified.
Production Environment : Once the Integration is certified, for the production usage client’s application should point to production environment.
3.1 Prerequisites
For a client to get access to SDK and do integration, client registration is mandatory.
Client has to obtain following values for following params :
Client Code (client_code) , that uniquely identify the client that is onboarded with the Khosla Labs.
API-Key (api_key ) , will be provided during onboarding and is used for managing subscription.
Salt ( salt), this is the salt for calculating hash of request payload and will be shared during onboarding. Each api_key will have its own salt.
Maven Credentials ( username and password )
For invoking initSDK Intent call client_code, api_key, and hash have to be mandatorily passed
3.2 SDK Integration ( Front End - Android )
Below mentioned are the steps to be followed for integrating FaceAuth SDK with client application.
3.2.1 Integrate FaceAuth SDK from maven repository
From the aadhaarbridge maven repository add the following code to build.gradle file.
Add the following dependency in client application’s project/build.gradle
allprojects {
.
.
.
repositories {
.
.
.
maven { url "https://jitpack.io" }
maven {
url "https://repo.aadhaarbridge.com/repository/android-sdk/"
credentials {
username '<<your username>>’
password '<<your password>>'
}
}
.
.
.
}
.
.
.
}
Add the following dependency in client application’s app/build.gradle
android{
.
.
packagingOptions {
pickFirst 'lib/armeabi-v7a/libRSSupport.so'
pickFirst 'lib/arm64-v8a/librsjni.so'
}
defaultConfig{
ndk{
abiFilters “arm64-v8a”, “armeabi-v7a”, “x86”, “x86_64”
vectorDrawables.useSupportLibrary true
renderscriptTargetApi 21
renderscriptSupportModeEnabled true
}
.
.
.
}
}
3.2.2 Configure Dependencies repository
Modify build.gradle file to add the following dependencies. In ( Module : app ) - build.gradle add:
dependencies {
.
.
.
implementation 'com.khoslalabs.faceauthsdk:base:<latest version>'
implementation 'com.khoslalabs.faceauthsdk:faceauthsdk:<latest version>'
}
3.2.3 Initiation of SDK
Insert the below code snippet with proper values for place holders in your application to invoke KLs FaceAuth SDK.
```CodeSnippet
- FaceAuthInitRequest.Builder faceauthInitRequestBuilder =
new FaceAuthInitRequest
.Builder(
<<your_client_code>>,
<<your_api_key>>,
<<your_user_id>>,
<<your_request_id>>,
<<calculated_hash>>,
<<your_operation_code>>,
<<your_salt>>
);
- FaceAuthRequestImage.getInstance().setFaceImage(faceImage);
//Applicable only for operation_code “LOGIN”’ , faceImage holds the user’s face image who should be authenticated and is already captured by the calling application.Authentication happens by comparing the faceImage against the live face which is captured by the SDK.
- myIntent.putExtra("init_request", faceAuthInitRequestBuilder.build());
FaceAuthInitRequest Parameter Details :
- <<your_client_code>> :
client_code that is assigned to you while onboarding.Please refer section Prerequisites.
- <<your_api_key>> :
api_key that is assigned to you while onboarding.Please refer section Prerequisites.
- <<your_operation_code>> :
operation_code is used to specify the purpose of SDK initiation. Possible values are “LOGIN” or “ENROLL”.
“LOGIN” - Indicates SDK Initiation is for Authentication Purpose.
“ENROLL” - Indicates SDK Initiation is for User Enrollment.
- <<your_user_id>> :
If operation_code is “LOGIN”’ , user_id indicates user_id of the user who has to be authenticated using the user face that is enrolled with KL System already either using ‘enroll’ API or FaceAuth SDK in ‘ENROLL’ mode.Please note that this is not a mandatory field and is applicable only in case user face is registered in Veri5Digital Platform.
If operation_code is “ENROLL”’ , user_id indicates user_id of the user who has to be enrolled and Face will be captured through the SDK.User will be enrolled with user_id and captured face image in KLs system.
- <<your_request_id>> :
Should be a unique Alphanumeric String of max length 64 for each SDK initiation.
- <<your_salt>> :
salt for calculating hash of request payload and will be shared during onboarding.
- <<calculated_hash>> :
This is the dynamic param that should be calculated during each SDK invocation. Refer Appendix C for hash calculation logic.
- Intent myIntent = new Intent(`<<calling_activity>>`, FaceAuthInitActivity.class);
// calling_activity refers to the calling applications class where this snippet is embedded.
- myIntent.putExtra("init_request", faceauthInitRequest);
- startActivityForResult(myIntent,`<<your_init_request_code>>`);
// your_init_request_code refers to the unique code that calling application is passing while invoking FaceAuth SDK, and this will be used for retrieving the results that SDK is returning.
### 3.2.4 Init SDK Response
Response from SDK will be received via onActivityResult method of the activity that invoke KL’s SDK.
Client Application will receive following three parameters via onActivityResult method :
- requestCode : The unique code ( Integer ) that client has passed while invoking SDK
- resultCode : Signifies the status of the SDK processing
- intentData : An intent containing data that is passed from SDK.
If SDK process is a successful transaction, client will get a FaceAuthResult object in intent .
If SDK process is unsuccessful transaction,client will get appropriate error_code and error_message.
Code snippet demonstrates the same :
```CodeSnippet
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == <your request code>) {
if (resultCode == FaceAuthResults.RESULT_OK) {
if (data != null) {
// use the user id
String userId = data.getStringExtra("user_id");
String matchScore =
data.getStringExtra("match_score");
//faceauthResponse object contains response data of the SDK
FaceAuthResponse faceauthResponse = data.
getParcelableExtra(“face_auth_result”);
}
} else {
if (data != null) {
// use the error code and error message
String userId = data.getStringExtra("user_id");
String error = data.getStringExtra("error_code");
String message = data.getStringExtra("message");
}
}
}
}
3.3 API - enroll
The primary objective of this API to register users with Veri5Digital Platform with a User Id and User Face. This registered face image can be used as a reference image for User Authentication where User Face can be captured using FaceAuth SDK in LOGIN mode.
Method : POST
Url : https://<hostname>
/face-auth/api/1.0/enroll
3.3.1 Request Payload
Please refer below Json for the request payload. Refer Appendix E for “headers” fields and description.
{
"headers":
{
"client_code": "<your_client_code>",
"sub_client_code": "<your_sub_client_code>",
"channel_code": "",
"channel_version": "",
"stan": "<a_unique_integer>",
"client_ip": "",
"transmission_datetime": "",
"operation_mode": "SELF",
"run_mode": "",
"actor_type": "",
"user_handle_type": "",
"user_handle_value": "",
"location": "",
"function_code": "DEFAULT",
"function_sub_code": "DEFAULT"
},
""Request":{
"api_key":"<your_api_key>",
"request_id":"<unique_request_id>",
"user_id":"<unique_user_id>",
"hash":"",// Generated Hash of the response payload
"location":"",
"txn_operation_code":"",
"user_image":"<base_64_encoded_string>"
}
3.3.2 Response Payload
Response:
{
"response_data": {
"User_id":"<unique user_id>",
"user_image":"base_64_encoded_string"
"location" : " "
"registration_time":"" //enroll api calling time
},
"response_status": {
"status": "<SUCCESS|FAIL>",
"code": "",
"message": ""
}
}
Appendix A: SDK Tech Specification
Recommended minimum tech specification for the smooth execution of Khosla Labs SDK to run on mobile devices is given below :
Mobile Operating System : Android 6 and above.
Camera Specification : 2 MP Minimum. 5 MP Front Camera ( > 30 fps ) with autofocus for optimal face capture.
Processor : Quad Core 2 GHz Clock Speed and above. Recommended 64 bit Octa Core for faster processing times.
RAM : Minimum RAM of 2 GB and 16 GB ROM (Recommended 4 GB RAM and 64 GB ROM).
Storage: 1 GB free storage space in the Phone for the SDK, Image Templates and Offline details to be stored (as per client requirements).
Lighting Condition: Capturing device should be placed in a reasonably lit environment for clear face and document capture. There should not be any reflection on the ID for accurate OCR extraction.
Network: Preferably 3G network and above for best results
Appendix B: SDK Major KPA
Khosla Labs has done an elaborate testing of the solution in a test control environment over a test data size of 200,000 sample data.
Following are key results -
Face match accuracy depends on the image quality, lighting, exposure, pitch, etc. We recommend taking a front facing selfie versus a side face. We have added an instructions page in our SDK to ensure a better success rate and a superior customer experience.
Under normal circumstances, Face match would happen under 1 second.
Our Solution works with industry lowest False Acceptance Rates (FARs) and False Rejection Rates (FRRs). FARs are below 0.1% and FRRs below 1%
Appendix C : Hash Generation
It is essential that we have a definitive protocol to verify the integrity of all the communication between Khosla Labs Platform and Client.
So for every request coming to KL, the client has to supply a hash which KL will use as the first step of verification.
In return, all responses will also contain hash supplied by KL Platform.
Hash Sequence is specified as follows(no space, no commas, no single/double quotes)
--> Initiate SDK Request : For InitiateSDK Intent call, use the following sequence for calculating hash.
client_code
|request_id
|api_key
|salt
--> Enroll API : In case client is using Enroll API, please use the following sequence for calculating hash.
client_code
|request_id
|api_key
|salt
Example(For _init request):
If your
client_code=a1b2c3,
api_key=123,
requestId=1234567890101112,
salt=e1d2c3b4a,
then
Hash-Sequence=a1b2c3|1234567890101112|123|e1d2c3b4a
hash =SHA-256(Hash-Sequence)
- Hash should be calculated using the following method:
hash=SHA256(Hash-Sequence)
Code snippet shows the sample code in Java for calculating hash.
private String calculateHash(String clientCode, String requestId, String apiKey, String salt) throws NoSuchAlgorithmException {
MessageDigest digest;
digest = MessageDigest.getInstance("SHA-256");
if (digest != null)
{
byte[] hash =
digest
.digest(
(clientCode + "|" + requestId + "|" + apiKey + "|" + salt)
.getBytes()
);
return bytesToHex(hash);
}
return null;
}
private final static char[] hexArray ="0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
For validation:
- Receiving end should calculate hash based on request parameters and match it against the received hash.
- If receivedHash=calculatedHash, then only you should proceed with your application logic.
api_key and salt are the key parameters here. It is known only to the client and Khosla Labs.
One api_key is mapped to one salt. This allows us to have multiple salts active at a time.
api_key and hash need to be passed in each API call. Salt is never transmitted in an API call.
Appendix D: Error Codes
Code | Scenario | Message |
---|---|---|
333 | SDK | There seems to be an unknown issue. Please try again later. |
555 | SDK | Transaction cancelled! |
888 | SDK | Please check your internet connection and retry. |
240006 | SDK | Subscription info not found. |
420001 | FaceAuth | api_key is mandatory. |
420002 | FaceAuth | request_id is mandatory. |
420003 | FaceAuth | user_id is mandatory |
420004 | FaceAuth | Invalid client_code |
420005 | FaceAuth | hash is mandatory. |
420006 | FaceAuth | Operation Code is mandatory. No such user-id exists |
420007 | FaceAuth | Txn Is is mandatory.Request Id is mandatory |
420008 | FaceAuth | User Id is mandatory |
420009 | FaceAuth | Hash validation failed |
420010 | FaceAuth | Invalid Client Code.Operation code is mandatory |
420011 | FaceAuth | User Id is empty |
420012 | FaceAuth | User already registered |
420013 | FaceAuth | user already registered |
420014 | FaceAuth | invalid client code. |
420015 | FaceAuth | Invalid Api Key. |
420016 | FaceAuth | Invalid Operation Code. |
420019 | FaceAuth | transaction_operation_code is mandatory |
420020 | FaceAuth | client_code is mandatory |
420021 | FaceAuth | User Id is empty |
333 | FaceAuth | Unexpected Error Occured |
Appendix E: Request Header Field Details
Below table details the header fields of the API request .Fields marked ( * ) are mandatory.
S.NO | Field Name | Description | Example |
---|---|---|---|
1 | client_code* | A unique code assigned to a client while onboarding. | client123 |
2 | sub_client_code* | Same as client_code if no special requirement is there. Its useful in case client needs any customization w.r.to different application. | client123 |
3 | actor_type* | Type of person who is making the request.If not relevant, "DEFAULT" can also be used. | CUSTOMER |
4 | channel_code* | Channel code used by the client to initiate the request. | ANDROID_SDK |
5 | stan* | System Trace Number - A unique number generated per request by the client. It is used to uniquely identify a request from a client. It can be used for troubleshooting. | 98321892319 |
6 | user_handle_type* | Indicates the type of the user identifier, who has initiated the request. Eg: UUID, MSISDN, EMAIL. If not relevant, "DEFAULT" can also be used. | |
7 | user_handle_value* | Value of user_handle_type.If not relevant, "DEFAULT" can also be used. | a@b.com |
8 | transmission_datetime* | Time in System Milli Seconds at which the request was initiated by the client. | 155325508029 |
9 | run_mode* | TRIAL - Indicates need for mock run of the transaction. No transaction posting will happen. REAL - Indicates the actual transaction posting request. If not relevant, "DEFAULT" can also be used. | REAL |
10 | client_ip | IP Address of the client device. | |
11 | operation_mode* | The way in which the request is executed. SELF - aadhaar holder doing the transaction. ASSISTED - where auth/ekyc is done in operator assisted mode. SYSTEM- where transaction is automated by system (batch processes). If not relevant, "DEFAULT" can also be used. | SELF |
12 | channel_version* | The version of the channel application like ANDROID_SDK. | 3.1.7 |
13 | function_code* | Indicates default behaviour for this api. If API is called from SDK, then value will be “SDK” if it API call, then value will be “API” | DEFAULT |
14 | function_sub_code | Indicates default behaviour for this api. If userImage is not present in request, then value will be “DEFAULT”, else value will be “FACE_LOGIN” | DEFAULT |
15 | request_id* | Client generated Id for referencing the transaction uniquely. | requestid123 |
16 | user_id | present in sdk response when user comes back to the client app. | userid123 |
16 | hash | Hash to be calculated by the client to verify the integrity of the request. Please refer APPENDIX C to see how to generate the hash. | |
18 | api_key* | api_key shared with the client during onboarding. | samplekey123 |
Appendix F : Proguard Rules
If the app requires obfuscation please add the below proguard rules in your app’s proguard-rules.pro file.
Note :
Proguard is a delicate tool, make sure you test your app thoroughly after enabling it.
#Preserve all annotations.
-keepattributes *Annotation*
#Preserve R.*.* things.
-keepclassmembers class **.R$* {
public static <fields>;
}
#Preserve things required for parcelable classes.
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator CREATOR;
}
#Preserve serializable things.
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID;
static final java.io.ObjectStreamField[] serialPersistentFields;
private void writeObject(java.io.ObjectOutputStream);
private void readObject(java.io.ObjectInputStream);
java.lang.Object writeReplace();
java.lang.Object readResolve();
}
# Preserve enums.
-keepclassmembers class * extends java.lang.Enum {
public static **[] values();
public static ** valueOf(java.lang.String);
}
# Preserve all .class method names.
-keepclassmembernames class * {
java.lang.Class class$(java.lang.String);
java.lang.Class class$(java.lang.String, boolean);
}
# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
native <methods>;
}
# Ignore support lib warnings.
-dontwarn android.support.**
# Preserve support libs.
-keep interface android.support.v4.** { *; }
-keep interface android.support.v7.** { *; }
-keep class android.support.** { *; }
# Preserve khosla labs libs.
-keep public class com.khosla.** { *; }
-keep class com.khosla.faceauthapi.** { *; }