Using secure properties

The Titanium SDK provides a Ti.App.Properties object, which provides a convenient way to persist user and application information. The Securely framework provides a familiar API designed to mirror Ti.App.Properties, which allows you to persist this information in a secure fashion. This recipe describes how to use the Securely.Properties object to store, read, and remove data in/from an encrypted and secure manner.

Getting ready

This recipe uses the Securely native module. This module and other code assets can be downloaded from the source provided by the book, or individually through the links provided in the See also section at the end of this recipe. Installing these in your project is straightforward. Simply, copy the modules folder into your project as shown in the following screenshot:

Getting ready

Adding the module reference

After copying the mentioned folder, you will need to click on your tiapp.xml file in Titanium Studio and add a reference to the bencoding.securely module as shown in the following screenshot:

Adding the module reference

How to do it...

This recipe is designed to run within the context of a Ti.UI.Window or other component within a single Titanium context. The code samples in this section demonstrate how to use the Secure properties of Securely using the same tests that Appcelerator uses for the Titanium SDK's Ti.App.Properties class. For more information, please refere to the app.js included with the recipe's source.

Creating the namespace

Once you have added the Securely module to your project, you need to create your application namespace in the app.js file and use require to import the module into your code as the following code snippet demonstrates:

//Create our application namespace
var my = {
  secure : require('bencoding.securely'),
  isAndroid : Ti.Platform.osname === 'android',
  testObjects:{
    testList : [
      {name:'Name 1', address:'1 Main St'},
      {name:'Name 2', address:'2 Main St'}	
    ]
  }
};

Creating the secure properties object

After the app namespace has been created, the next step is to create a new properties object. This object contains the following property values that must be set at creation time:

  • secret: This is a required parameter. secret is the password used to encrypt and decrypt all property values. The same secret used to encrypt must be used during the decryption process or a null value will be returned.
  • identifier: This parameter is optional. If no value is provided, the bundle name on iOS or the PackageName on Android is used. identifier allows you to segment each property with an identifier, if needed.
  • accessGroup: This parameter is an optional value used on the iOS platform. Access groups can be used to share keychain items among two or more applications. If no access group is provided, the keychain values will only be accessible within the app saving the values.
  • encryptFieldNames: This parameter is an optional value only used on the Android platform. When set to true, Securely will create an MD5 hash using the provided secret for all property names.
    var properties = my.secure.createProperties({
      secret:"sshh_dont_tell",
      identifier:"myPropertyIdentifier",
      accessGroup:"myAccessGroup",
      encryptFieldNames:false
    });

Result comparison helper

The displayResults function shown in the following code snippet is used to compare the test result with the expected value. Based on the comparison, the proper message is generated for presenting to the user.

function displayResults(result, expected) {
  if (result instanceof Array) {
    return displayResults(JSON.stringify(result), 
    JSON.stringify(expected));
  }else{
    if (result === expected) {
      return "Success ("+result+"=="+expected+")";
    } else {
      return "Fail: " + result + "!=" + expected;
    }
  }
};

Reading secure properties without defaults

Each supported property type has a get method. For example, to read a Boolean property, the getBool method is called and a name is provided. This API works similar to the Ti.App.Properties object within the Titanium SDK, with added support for reading and decrypting secure properties. If no stored value is available, a null or default value type is provided. The following snippet demonstrates how to read saved secure property values:

Ti.API.info('Bool: ' + displayResults(properties.getBool('whatever'),
(my.isAndroid ? false : null)));

Ti.API.info('Double: ' + 
displayResults(properties.getDouble('whatever'),
(my.isAndroid ? 0: null)));

Ti.API.info('int: ' + displayResults(properties.getInt('whatever'),
(my.isAndroid ? 0 : null)));

Ti.API.info('String: ' + 
displayResults(properties.getString('whatever'),null));

Ti.API.debug('StringList: ' + 
displayResults(properties.getList('whatever'),null));

Note

On iOS, null values are returned for any property without a saved value. Due to Android's type system, Boolean values will return false if no value is stored and numeric values will return zero. All other Android values will return null similar to iOS.

Reading secure properties with defaults

Also similar to Ti.App.Properties, Securely provides the ability to read and decrypt a secure property and provide a default value if there is no stored value for the requested secure property.

Ti.API.info('Bool: ' + 
displayResults(properties.getBool('whatever',true),true));

Ti.API.info('Double: ' + 
displayResults(properties.getDouble('whatever',2.5),2.5));

Ti.API.info('int: ' + 
displayResults(properties.getInt('whatever',1),1));

Ti.API.info('String: ' + 
displayResults(properties.getString('whatever',"Fred"),"Fred"));

Ti.API.debug('StringList: ' + 
displayResults(properties.getList('whatever'),testList));

Note

The default value is not encrypted or persisted during the read process.

Setting secure property values

Each supported property type has a set method used to encrypt and persist values. For example, to save and encrypt a Boolean property and the setBool method, and provide a property name and Boolean value. This API works similar to the Ti.App.Properties object within the Titanium SDK. Securely supports both encrypting and writing the value to the secure properties directly. The following code snippet demonstrates how to save the following values to secure and encrypted storage:

properties.setString('MyString','I am a String Value '),
properties.setInt('MyInt',10);
properties.setBool('MyBool',true);
properties.setDouble('MyDouble',10.6);
properties.setList('MyList',my.testObjects.testList);

To demonstrate the properties were saved correctly, the get method is called for each file and the results are printed to the console within Titanium Studio.

Ti.API.info('MyString: '+ properties.getString('MyString'));
Ti.API.info('MyInt: '+ properties.getString('MyInt'));
Ti.API.info('MyBool: '+ properties.getString('MyBool'));
Ti.API.info('MyDouble: '+ properties.getString('MyDouble'));
var list = properties.getList('MyList'),
Ti.API.info('List: ' + JSON.stringify(list));

Listing secure property field names

The property names can be returned as an array by calling the listProperties method on the Securely property object. The following code snippet demonstrates how to use this method to print a JSON representation of the names array to the console within Titanium Studio.

if(!properties.hasFieldsEncrypted()){
  var allProperties = properties.listProperties();
  Ti.API.info(JSON.stringify(allProperties));
}

Note

If field name encryption is enabled, the listProperties method will return null. As the field names are encrypted with a one-way hash, the original names are no longer available.

Removing secure properties

You can remove properties using two methods on the Securely properties object. The removeProperty and removeAllProperties are designed to be familiar and mirror the methods with the same name on the Titanium SDK's Ti.App.Properties object.

The removeProperty method will remove the provided secure property name, if it exists.

properties.removeProperty('MyInt'),

The removeAllProperties method will remove all properties within the identifier provided when creating the properties object.

properties.removeAllProperties();

Note

In our recipe, the remove property functions are called at the end of the test so that the results can be recreated reliably each time.

Check if a secure property exists

The Securely property object provides the hasProperty method to provide the ability to check if a secure property exists. If the property exists, a Boolean true value is returned, otherwise a result of false is provided. This API is designed to be familiar as it mirrors the Ti.App.Properties.hasProperty function within the core Titanium SDK.

Ti.API.info("Does MyInt property exist? " + 
properties.hasProperty('MyInt'));

How it works...

The underlying infrastructure for secure properties is implemented differently depending on the platform running your application. Although Securely provides a cross-platform API, it is important to understand how each platform has been implemented and its associated security considerations.

Secure properties on iOS

The Securely framework saves all property values as serialized strings within the iOS Keychain. This provides secure storage and since it is part of iOS does not require any dependencies. Since Securely uses the iOS keychain service, it is recommended that your organization review Apple's Keychain documents before storing sensitive data within the securely-managed container.

Note

It is important to remember since the iOS Keychain service is used, your Secure Property values will still be available within the iOS Keychain after your app has been uninstalled. The removeAllProperties method must be called if you wish to remove all keychain items before removal of the app.

Secure properties on Android

The Securely framework saves all property values as serialized and AES-encrypted strings into Android's SharedPreferences. Although Android introduced native keychain support in API level 14, the Securely module was designed to accommodate a larger number of devices and targets API level 8 and higher. It is recommended that your Enterprise reviews the secure properties' implementation within Securely to ensure it is in compliance with your corporate or industry standards and requirements.

Secure property considerations

By default on Android, the property names are not encrypted. This can be enabled by setting the encryptFieldNames on creation of the properties object. Due to the need to encrypt all property names, this property can only be set on creation of a new properties object. When field name encryption is enabled, Securely will create a SHA-1 hash for each field name using the secret property value provided. Enabling this feature creates performance considerations. Regression and performance testing is recommended before implementing your existing Titanium app.

See also

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.182.76