Encryption as a Service SDK for Xamarin

The IDENTOS SDK allows you to secure application data and enables applications to encrypt, decrypt and share access to data across multiple devices and users. IDENTOS provides simple interfaces to register a device to your application, authenticate your users, and access the data protected by our encryption key management system.

Main functions of the SDK:

Register a Device
An application must register the user and device before the IDENTOS service can be initialized. When the device is registered, it is associated to the application and user and is subsequently governed by the key management policies set by the administrator.

Authenticate & Authorize
IDENTOS provides the ability to enforce a PIN entry upon application launch to ensure the user is authenticated. This PIN helps to secure the user's private key which is used to protect data and digitally sign requests for keys. The PIN can be set to 0 to disable PIN Required as a feature, however this is not recommended. 

Control access to data
Encrypt and decrypt any given piece of data, grant users access to the encryption keys, and maintain compliance by logging every request for data and keys.

Getting Started

Download the SDK

Contact us to request the SDK

Install the Framework

The identos Xamarin SDK comes in form of a nuget plugin, .nupkg file.

1.  Add the directory containing the nuget plugin as a package source. This can be done with the NuGet Package Manager UI. More about this here.
2.  Install the Identos Nuget Plugin from this source. More about this here.
3.  To take advantage of Xamarin's cross-platform functionality, install the plugin into your Xamarin PCL project and your Xamarin.Andriod and Xamarin.iOS projects.
4.  After this, you can make use of Identos functionality in the Xamarin.PCL project and it will work on both Android and iOS platforms.

Initialize the SDK

You can find your appId and clientKey on your app’s admin page.

/**
* Initialize Identos SDK
*
* param appid Your app id, provided by Identos
* param client keyYour client key, provided by Identos
* param version Your app version, allows different security policies based on version
* param livemode choose either live or sandbox configuration
* param path device filepath for identos generated files(for android, this value is not used in iOS)
*/
IdentosStatus initialize(string appid, string clientkey, string version, bool livemode, string path);

Usage
using Plugin.Identos;
using Plugin.Identos.Abstractions;



appId = "a-00001";
appkey = "a-00001-key-c";
version = "4";
livemode = false;
path = "data/data/identos" //get current app path for android, can supply empty string for iOS

IdentosStatus status = CrossIdentos.Current.initialize(appid, appkey, version, false, path);

if(status == IdentosStatus.DeviceUnregistered)
{
//register device
}
else if(status == IdentosStatus.Success)
{
//initialization successful
}
else
{
//error initializing SDK
}

Registering the Users Device

The first step in the implementation of IDENTOS encryption services is to register the user’s device. This provides the first factor of authentication (what the user has). Only once a device has a registered identity with the IDENTOS trusted server can authentication take place. You can optionally require a user PIN, which is the second factor of authentication. Read more about user PIN below.

The process of registration is comprised of two main parts. The first part is completed by the code in the client application (registering the device) and the output of that is an identifier called a ‘device package’ that can be used in the second step to complete the registration.

Once the client has generated a device package, the package is passed to the server, which in turn completes the registration by verifying the user and passing the package back to the IDENTOS SDK using the Post user/register API.

In the Client Application

Get the Device Package

/**
* Creates a string that a backend application can use to register this device on the Trusted Server

* param pin The users passphrase, used to secure their local key
* returns devicePackage to be sent to /user/register endpoint
*/
string device_package(string pin);

Usage
string devicePackage = CrossIdentos.Current.device_package(pin);

In the Back End

POST user/register
https://sandbox.identos.ca

Purpose

Register a new user with the trusted server. Usernames must be unique in your application. If a username already exists, an additional device is added to that username.

Request

{
appid : "appid"
serverkey : "private server id key"
username : "application unique username"
device-package : "device package to register with this user"
}

Response

HTTP 200


{ "userid"  : "1234" }

Curl Example

#! /bin/bash

curl -X POST \
-H "Content-Type: application/json" \
-d '{
"appid": "appid",
"serverkey": "servicekey",
"username": "username-uniqueidentifier",
"device-package": "eyJkZXZpY2VfaWQiOiAidUs1QlhYUHpFK250SkUvcDFKM0VMY3JIU1V4MyIsICJleHAiOiAiQVFBQiIsICJtb2QiOiAiNjZmdk10d2lCKzZDM1RWVGVmWEovdDB4NU81K3hIYkJ0ZVBZQ2pxYkQ3WmdHdEY2NlBuZXhjMkdmV05Pcms4RDNsK2xOMzVjUHNZOE02dEN0WG5HU256S0loUEJ1NjZSWTZoV1Z0Y2FhUmdPbHIyNGdPQjA0MnRobmhnZjY3SHpRSllnZjE0SlRjcFFuc1VBazh4bjZHQmJ4Q2V1RTZ0S05oRlZSWmpETFE4VXY3V0taOXFlNmRTNm1IZURkMjZiemJqUXVkeEIwMDBJTGJqMkF5U3hwNFdqbk81c1JmTURxNkluZ0ZYMkRINGI5QUJuUTlONGJPQ0Y4UUNibnl0ZWwwYXhvcEhmL0RKbWJHd3U1N0kvV2t4N0YyZ3hxUlA0Z25XU0R5cWl3QXkwZEQ2NXp0QVJVWnNqNkViQjRsTi9xK2I4QmpHK3MxWTdxQjlIR09ZLzZRPT0ifQ=="
}' \ 
https://sandbox.identos.ca/api/v0/user/register


Authenticating the User

Authentication allows access to IDENTOS functions such as encryption, decryption, and granting access to private keys. Authentication will not succeed unless a device has been registered.

User PIN

An optional feature, requiring the user to enter a PIN provides the second authentication factor (what the user knows) which helps protect the device’s private key at rest. You should request the PIN just in time to use it, and not keep it around longer than necessary.

Depending on the configuration of your app, a user supplied PIN may be required during steps such as registering a user device, authentication, or data encryption functions.

Example

/**
* Authenticates the user of the SDK
*
* param pin The users passphrase, the same one used at register
* returns IdentosStatus
*/

IdentosStatus authenticate(string pin);

Usage
IdentosStatus status = CrossIdentos.Current.authenticate(passphrase)

if(status == IdentosStatus.Success)
{
//user authenticated
}
else if(status == IdentosStatus.Failed)
{
//authentication failed
}

Encryption Functions

Encryption functions include encryption of data, the decryption of data, and granting user access. These functions only succeed after the application has been successfully authenticated.

Interface

IdentosReturnData

     /// Result class which encapsulates the result of an operation by the Identos SDK.
public class IdentosReturnData
{

/// status of operation
public int status;

/// identifier for the result of the operation(can be null)
public string identifier;

/// resulting data from the operation in bytes(can be null)
public byte[] data;
}

Encryption

/**
* Encrypts some data with a key retrieved from the trusted server
* param plaintext data to encrypt in bytes
* param identifier Optional key identifier(null allowed)
*/
IdentosReturnData encrypt(byte[] plaintext, string identifier);

Usage
IdentosReturnData result = CrossIdentos.Current.encrypt(plaintext, identifier);

Decryption

/**
* Decrypts some data that was previously encrypted by the sdk
* param cipherdata Ciphertext to decrypt, this is the data property returned from the previous encryption operation
* return data class which encapsulates the result of an operation by the identos SDK
*/
IdentosReturnData decrypt(byte[] cipherdata);

Usage
IdentosReturnData result = CrossIdentos.Current.decrypt(cipherdata);

Signing

/**
* Sign arbitrary data with this users private key
* param data data message to be signed
* returns IdentosReturnData instance which encapsulates the result of an operation by the identos SDK
*/
IdentosReturnData sign(byte[] data);

Usage
IdentosReturnData result = CrossIdentos.Current.sign(data);

Verify

/**
* Verify a signature created by the SDK sign function
* param signature signature for message in byte array form
* param data signed message
*/
IdentosStatus verify(byte[] signature, byte[] data);

Usage
IdentosStatus status = CrossIdentos.Current.verify(signature, data);

Grant

/**
* Grants access to a resourceIdentifier from a group of users
* param identifier Key identifier for encrypted data to grant access too.
* param to_userid User id to grant access to, id from user/device pair registration
* returns return data instance which encapsulates the result of an operation by the identos SDK
*/
IdentosStatus grant(string identifier, string to_userid);

Usage
IdentosStatus status = CrossIdentos.Current.grant(identifier, userId);

Handling the result of encryption functions

if((IdentosStatus)result.status == IdentosStatus.Success)
{
//operation successful
//access result of operation using the result.data field and the identifier
//using the result.identifier field.
}

Errors

IDENTOS uses response codes to indicate sucess or failure of a request

Response Codes

public enum IdentosStatus
{

/// Operation completed successfully
Success = 0,

/// Operation failed
Failed = -1,

/// operation failed and is in an invalid state.
InvalidState = -2,
InvalidParameter = -29,

/// Initialization call completed successfully but current device is yet to be registered by user
DeviceUnregistered = -50,

/// The submitted PIN was invalid (didn't meet length/format requirements)
InvalidPin = -101,

/// The submitted PIN was valid, but incorrect
WrongPin = -102,

/// This method requires an internet connection
NoInternetAccess = -200
}