Securing sensitive data such as encryption keys
For heightened security of especially sensitive data, such as encryption keys and passwords, you can use the classes ACSensitiveData or ACSensitiveMutableData. These classes use the Apple hardware known as Secure Enclave. By using these classes, you reduce the sensitive data’s attack surface, because the sensitive data is stored in the Secure Enclave rather than in plain-text in memory. Without these classes, sensitive data such as keys are stored in memory, and therefore can be captured in a memory dump.
To benefit from these classes, the device must:
• | have Apple’s Secure Enclave hardware. |
Devices that have biometric security have Secure Enclave hardware.
• | be running iOS 11 through the most recently released version as supported by MobileIron |
• | be running Mobile@Work 9.8 for iOS through the most recently released version as supported by MobileIron |
MobileIron Go does not support this feature.
Securing sensitive data involves the following:
• | Coding your app to secure sensitive data |
• | Configuring the MobileIron server to secure sensitive data for your app |
• | Debugging ACSensitiveData usage |
Coding your app to secure sensitive data
The interfaces to use are:
@interface ACSensitiveData : NSData
@interface ACSensitiveMutubleData : ACSensitiveData
@interface ACSensitiveDataContainer : NSObject
These interfaces are defined in ACSensitiveData.h.
To secure your data, such as encryption keys, create an ACSensitiveData or ACSensitiveMutableData object and populate it with your sensitive data.
For data that you want to keep for a long time period, create an ACSensitiveDataContainer to hold the ACSensitiveData or ACSensitiveMutableData object.
ACSensitiveData *key = [ACSensitiveData dataWithBytes:keyData.bytes length:keyData.length]; ACSensitiveDataContainer *containerizedKey = [ACSensitiveDataContainer containerWithData:key];
let key = ACSensitiveData(bytes: keyData.bytes, length: UInt(keyData.length)) let containerizedKey = ACSensitiveDataContainer(data: key)
NOTE: | Do not use the ACSensitiveData methods -copyWithZone: or -mutableCopyWithZone:. |
Configuring the MobileIron server to secure sensitive data for your app
The MobileIron server administrator configures whether the ACSensitiveData and ACSensitiveMutableData objects are secured with Apple’s Secure Enclave. The administrator configures this choice per AppConnect app. Therefore, in the documentation you provide the MobileIron server administrators, specify that your app uses the Secure Enclave if it is available.
The MobileIron server administrator uses the key named MI_AC_CONTAINER_TYPE in the app’s app configuration. The AppConnect library consumes this key. It is not passed to your app in Its configuration key-value pairs.
The possible values for MI_AC_CONTAINER_TYPE are:
Value |
Description |
ENCLAVE |
ACSensitiveData and ACSensitiveMutableData objects are stored in the Secure Enclave, if available on the device. |
LOCAL |
ACSensitiveData and ACSensitiveMutableData objects are not stored in the Secure Enclave. |
Debugging ACSensitiveData usage
Because it is a hardware feature, you cannot test Secure Enclave usage in the iOS simulator. However, when running in debug mode on a device or in the iOS simulator, you can use the following environment variables on your app to check if your ACSensitiveData objects are being held in memory for too long. The value of MI_AC_CONTAINER_TYPE has no impact on using these environment variables.
• | AC_SENSITIVE_DATA_MAX_LIFETIME |
Set its value to a number of seconds. An exception is raised if an ACSensitiveData or ACSensitiveMutableData object is not deallocated before the specified number of seconds since its allocation. The call stack points to where the object was allocated.
• | AC_SENSITIVE_DATA_MAX_RUN_LOOP_ITERATIONS |
Set its value to a positive integer. An exception is raised if an ACSensitiveData or ACSensitiveMutableData object is not deallocated before the run loop in which is was allocated completes the specified number of iterations. The call stack points to where the object was allocated.