Knox Sensitive Data Protection provides protection of Data-at-rest (DAR) in your app. This protection is provided with minimum development effort and at a negligible user experience loss.
Data at rest is a term referring to inactive data stored in any digital form, for example, in files or 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, and so on).
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.
|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|
There are 2 packages you can use with SDP:
|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 the following three key classes to manage SDP.
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:
<application>element. Add the following child
<meta-data>. Doing so enables SDP for your app.
<android>meta-data android:name="sdp" android:value="enabled"</android>
The Knox framework automatically creates the SDP default engine upon the workspace creation. No additional coding is required.
//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
//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 using
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 back up-PIN from the user (If the user forgets this PIN, the engine cannot be unlocked, and the data is 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:
During engine creation, the app that invokes
addEngine is the "engine owner". You configure privileged apps by calling
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"));
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.
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 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);