Menu

Sensitive Data Protection (SDP)

On this page

Knox Sensitive Data Protection provides protection of Data-at-rest (DAR) in your app. This is done with minimum development effort and at a negligible user experience loss.

About SDP

Data at rest is a term referring to inactive data stored in any digital form (e.g. files, databases); protecting DAR is an increasing concern for businesses due to the rise of sophisticated malicious attacks. Using the Knox Sensitive Data Protection (SDP) APIs, you can easily secure your app’s confidential data, protecting apps from data leakage if devices are stolen or compromised. SDP encrypts your app-data and remains that way until the device owner provides authentication(pattern, pin, password, fingerprint, etc).

For example:

Internal messaging apps used by employees often transmit confidential data between co-workers or clients; this can include pictures, invoices, emails or contracts. Knox SDP ensures sensitive data stored within the app is inaccessible until the device owner unlocks it. Your data can be protected if a device is lost, stolen or shared with the wrong individual.

There are 2 ways Knox can mark your data to help keep it secure: protected or sensitive.

Feature Activation Accessibility
Protected Data By default for data in a Knox container Accessible after device boots up normally
Sensitive Data By SDP APIs Accessible only when in SDP unlocked state

How SDP works

SDP packages

There are 2 packages you can use with SDP:

Package Function
com.samsung.android.knox.sdp Provides classes that allows you to mark application data as sensitive and other utility functions.
com.samsung.android.knox.sdp.core Provides classes that allow you to create and control SDP engines.

The Samsung Knox SDK provides three key classes to manage SDP:

  1. SdpFileSystem - This file system allows you to define and access your protected and sensitive data.
  2. SdpDatabase - This lets you configure column-level database encryption.
  3. SdpEngine - The SDP platform offers multiple engines to support Android Multi-User Framework and individual app passwords. You can select the engine used for encrypting data on a device or in a Knox container. The SdpEngineclass supplies a password-derived KEK to the encryption layer. Each SdpEngineinstance holds its own state machine that eventually affects the encryption layer. When transitioning from the unlocked to locked state, password-derived KEKs are cleared from memory (both the user space and OS kernel) to protect sensitive data from being decrypted.

There are two types of SDP engines:

Default Engine:

  • Uses the default authentication method set in the Knox container (pattern, pin, password, fingerprint, etc).
  • How it works: The selected data gets encrypted and decrypted using cryptographic keys obtained from Knox user credentials authenticated.

Custom Engine:

  • For extra protection, a custom password is used in the app to protect data.
  • Individual apps that create custom engine are responsible for encryption / decryption.
  • Requires additional development effort.
  • How it works: The selected data gets encrypted and decrypted using cryptographic keys obtained from the individual application authenticated.

SDP examples

In this section

Add SDP support to your app

  1. Extract the knoxsdk.jar an from the Knox SDK. Add these to files to the libs folder of your Android project.
  2. Open AndroidManifest.xml and locate the <application> element. Add the following child <meta-data>. This enables SDP for your app.
<android>meta-data android:name="sdp" android:value="enabled"</android>
  1. Create a BroadcastReceiver class. This allows you to display custom text to see if your license activation is successful.
  2. Activate your Knox license
  3. Create the SDP engine.

Create the default SDP engine

The Knox framework automatically creates the SDP default engine upon the workspace creation. No additional coding is required.

Create the Custom SDP engine

//Create SdpCreationParam

int flag = SdpEngineConstants.Flags.SDP_MDFPP;
SdpCreationParamBuilder sdpCreationParamBuilder = new SdpCreationParamBuilder(myapp.alias, flag);

builder.addPrivilegedApp(new SdpDomain("myapp.alias", "com.myapp.keyguard"));
builder.addPrivilegedApp(new SdpDomain("myapp.alias", "com.myapp.agent"));

//addEngine

SdpEngine.getInstance().addEngine(builder.getParam(), password, resetToken)

Custom Engine: Lock

The SDP engine maintains its encryption key based on its lock state. When a user requests to unlock it with a password, the SDP framework retrieves the key for decryption and keeps it in memory until it's locked. We strongly recommend you have a password timeout code in your system in order to protect data when it's not in use. Keys for encryption are available since boot, so you can still create new sensitive data regardless of the lock state.

to lock an SDP engine, use sdpEngine.lock("myapp.alias");.

//recommended code for lock()

sdpEngine = SdpEngine.getInstance();
sdpEngine.lock("myapp.alias");
 
//recommended code for unlock()
sdpEngine = SdpEngine.getInstance();
sdpEngine.unlock("myapp.alias", "my_password");

Custom Engine:  Change/reset/password

Changing the password is only allowed in an unlocked state. This is the normal scenario when a user inserts an old password and update to a new password.

If a user forget the password, it can be reset with resetPassword(). This requires a new password and a reset token that you provided during engine creation via addEngine(). We recommend you don't store this reset token in the device but on your private server. If you don't have a server, you can take a backup-PIN from the user (If the user forget this PIN, the engine cannot be unlocked, and the data will be erased.)

//recommended code for setPassword()

SdpEngine sdpEngine;
sdpEngine = SdpEngine.getInstance();
sdpEngine.setPassword("myapp.alias", "new_password");
	
//recommended code for resetPassword()

SdpEngine sdpEngine;
sdpEngine = SdpEngine.getInstance();
sdpEngine.resetPassword("myapp.alias", "new_password", "my_reset_token");

Custom Engine: Access restriction

There are three components to SDP design if you need to create a custom engine:

  • The engine owner:creates the engine. Grants privileges to apps to control the engine.
  • The privileged app: ties the app to the engine (lock/unlock, change/reset password)
  • The app user: marks user data as sensitive.

During engine creation, the app that invokes addEngine is the "engine owner". You configure privileged apps by calling SdpCreationParam.addPrivilegedApp(). SdpDomain represents the app installed in the system to apply policies.

int flag = SdpEngineConstants.Flags.SDP_MDFPP;	
SdpCreationParamBuilder sdpCreationParamBuilder = new SdpCreationParamBuilder(myapp.alias, flag);
builder.addPrivilegedApp(new SdpDomain("myapp.alias", "com.myapp.keyguard"));
builder.addPrivilegedApp(new SdpDomain("myapp.alias", "com.myapp.agent"));

Package, data deletion

The Android framework supports the ability to delete cache/data for end users. To remove data, users go to Settings -> Application Manager. Encrypted directories are removed for the app accordingly.

Set data as sensitive

At this point your SDP engine is ready to protect your data. You just need to call the setSensitive API on that data.

Setting files as sensitive

Construct a new SdpFileSystemobject which can be used to manipulate file(s) as sensitive. You can call setSensitivefor files at any point of time.

String alias = "sdpDemo"; // in case of default engine alias will be null.
SdpFileSystem sdpFileSystem = new SdpFileSystem(Context, alias);
File file = new File(sdpFileSystem.getFilesDir(), "file_path");
sdpFileSystem.setSensitive(file)

Setting database columns as sensitive

You can call the setSensitive API only in the unlocked state. It's recommended that after SDP engine creation you can call setSensitive on database columns that you want to protect:

String alias = "sdpDemo"; // in case of default engine alias will be null.
SdpDatabase sdpColumn = new SdpDatabase(alias);
List < String > columnsList = new ArrayList < String > ();
columnsList.add("column1");
columnsList.add("column2");
sdpColumn.setSensitive(mDb, null, "table_name", columnsList);