Securely save keys in mobile devices

How to save keys securely in iOS and Android devices

January 29, 2017 - 3 minute read -
code cordova ios android

Introduction

For securely saving key, password or string in mobile application especially in cordova apps there is different approaches for different platforms.

Implementation

  • For set/get key in iOS implementation can be something like below using KeychainWrapper
/* set */
KeychainWrapper* keychain = [[KeychainWrapper alloc]init];
[keychain mySetObject:value forKey:(__bridge id)(kSecValueData)];
[keychain writeToKeychain];
/* get */
KeychainWrapper* keychain = [[KeychainWrapper alloc]init];
NSString *value = [keychain myObjectForKey:@"v_Data"];
  • For set/get key in Android implementation can be something like below ``
/* set */
KeyStore keyStore = KeyStore.getInstance(Constants.KEYSTORE);
keyStore.load(null);

if (!keyStore.containsAlias(alias)) {
    Calendar start = Calendar.getInstance();
    Calendar end = Calendar.getInstance();
    end.add(Calendar.YEAR, 1);
    KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(
            getContext())
            .setAlias(alias)
            .setSubject(new X500Principal("CN=" + alias))
            .setSerialNumber(BigInteger.ONE)
            .setStartDate(start.getTime())
            .setEndDate(end.getTime())
            .build();

    KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", Constants.KEYSTORE);
    generator.initialize(spec);

    KeyPair keyPair = generator.generateKeyPair();

    Log.i(Constants.TAG, "created new key pairs");
/* get */
KeyStore keyStore = KeyStore.getInstance(Constants.KEYSTORE);
keyStore.load(null);
PrivateKey privateKey = (PrivateKey) keyStore.getKey(alias, null);


Cipher output = Cipher.getInstance(Constants.RSA_ALGORITHM);
output.init(Cipher.DECRYPT_MODE, privateKey);
CipherInputStream cipherInputStream = new CipherInputStream(
        new ByteArrayInputStream(KeyStorage.readValues(getContext(), alias)), output);

ArrayList<Byte> values = new ArrayList<Byte>();
int nextByte;
while ((nextByte = cipherInputStream.read()) != -1) {
    values.add((byte)nextByte);
}
byte[] bytes = new byte[values.size()];
for(int i = 0; i < bytes.length; i++) {
    bytes[i] = values.get(i).byteValue();
}

String finalText = new String(bytes, 0, bytes.length, "UTF-8");
callbackContext.success(finalText);

Available cordova plugins “cordova-plugin-secure-key-store”

This plugin store key, password or string securely to Keychain and Keystore in iOS and Android respectively.

Installation

The plugin can be installed via the Cordova command line interface:

$ cordova plugin add cordova-plugin-secure-key-store

or via github

$ cordova plugin add https://github.com/pradeep1991singh/cordova-plugin-secure-key-store

Usage of cordova-plugin-secure-key-store

  • This plugin will add two new methods to window scope, one is for encrypting and other for decrypting keys.
  • For saving string cordova.plugins.SecureKeyStore.set and for retrieving cordova.plugins.SecureKeyStore.get.
cordova.plugins.SecureKeyStore.set(function (res) {
  console.log(res); // res - string securely stored
}, function (error) {
  console.log(error);
}, "key", 'string to encrypt');
cordova.plugins.SecureKeyStore.get(function (res) {
  console.log(res); // res - string retrieved
}, function (error) {
  console.log(error);
}, "key");
  • Apart from above there is one more method for removing saved key
cordova.plugins.SecureKeyStore.remove(function (res) {
  console.log(res); // res - string removed
}, function (error) {
  console.log(error);
}, "key");

Summary

Source code available at cordova-plugin-secure-key-store