To offer the highest protection possible for the generated private keys within the hardware security module (Secure
Enclave/Android Keystore), the XignSys SDK requires that the mobile device is secured with a lock (PIN, Password,
Pattern etc.) starting with version 4.2.0. Whether the SDK should require a device lock can be configured with
XignSdkConfig.Builder.setKeyGenerationStrategy(deviceLockRequired:); the new default behaviour
is DeviceLockRequired.required.
Note iOS: Prior to version 4.2.0 of the XignSys SDK the behaviour of the key generation on iOS was equal to the mode
DeviceLockRequired.ignored. This has now been changed toDeviceLockRequired.required.
Note Android: On Android API levels lower than 28 key protection via a device lock is not supported. These API levels will always behave like
DeviceLockRequired.ignored. However, if the device gets a system update which raises the API level to at least 28, the configured mode will behave as described (DeviceLockRequired.requiredis default).
Due to this update the XignSys SDK can now throw following error codes during the initialization:
XignSdkInitializationErrorCodes.deviceLockNotSet (XignSdkInitializationErrorCodes.DEVICE_LOCK_NOT_SET)XignSdkInitializationErrorCodes.keyRemovedBySystem (XignSdkInitializationErrorCodes.KEY_REMOVED_BY_SYSTEM)XignSdkInitializationErrorCodes.DEVICE_LOCKEDAn example of how to obtain these error codes is illustrated at the beginning of chapter Usage.
The case XignSdkInitializationErrorCodes.deviceLockNotSet can only occur during the initialization of the XignSys SDK,
if the option DeviceLockRequired.required is used. To avoid this error the app should preemptively check if a device
lock is set. For example, this can be done as follows:
private func checkIfDeviceLockIsSet() -> Bool {
var errorOpt: NSError? = nil
let isPasscodeSet = LAContext().canEvaluatePolicy(.deviceOwnerAuthentication, error: &errorOpt)
if let error = errorOpt,
error.domain != LAErrorDomain,
error.code != LAError.Code.passcodeNotSet.rawValue {
// handle unexpected error or ignore it
}
return isPasscodeSet
}
private fun checkIfDeviceLockIsSet(context: Context): Boolean {
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as? KeyguardManager
return keyguardManager?.isDeviceSecure ?: false
}
The case XignSdkInitializationErrorCodes.keyRemovedBySystem can occur, if either the
option DeviceLockRequired.required (default value)
or DeviceLockRequired.automatic was used during the initialization of the XignSys SDK. This error indicates a state
where a previously created key has been removed by the system because the device lock has been disabled. Besides during
the initialization of the XignSys SDK this error can also be thrown by various flow functions of the SDK,
e.g. ParseProcessInitializationDataErrorCodes.keyRemovedBySystem. Due to the fact that the keys have been irrevocably
removed from the system, the only solution is to fully reset the XignSys SDK; see Reset the SDK. Note
that after this step the SDK needs to be personalized again.
The case XignSdkInitializationErrorCodes.DEVICE_LOCKED can only happen on Android, because applications can run in the
background. Similar to the error case XignSdkInitializationErrorCodes.keyRemovedBySystem it can only occur if the
modes DeviceLockRequired.required (default value) or DeviceLockRequired.automatic are used. If one of these modes is
used and the XignSys SDK is initialized in the background while the device is locked, this error is thrown. To prevent
this error from happening the app should make sure that the SDK is only initialized while the device is unlocked. For
that purpose the following code block can be used:
private fun checkIfDeviceIsLocked(context: Context): Boolean {
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as? KeyguardManager
return keyguardManager?.isDeviceLocked ?: false
}
Another solution would be to simply close the app, if the error occurs while the app is in the background.
If preferred/required the key generation behavior can also be changed to match versions prior to 4.2.0 by using the
mode DeviceLockRequired.ignore. In this mode, generated keys can not benefit from the additional protection the device
lock offers. Hence, using this mode reduces the security, especially in cases of device theft. Beware of this drawback
before choosing this mode, since sensitive data should be protected with every measure available.
Important: The mode
DeviceLockRequired.requiredis mandatory for the Servicekonto.NRW setup and must not be changed in this case.
The mode can be changed as follows:
private func changeDeviceLockRequired() {
let config = XignSdkConfig.with { builder in
builder.setKeyGenerationStrategy(
// one of `DeviceLockRequired.ignored/automatic/required`
deviceLockRequired: DeviceLockRequired.ignored
)
}
do {
try XignSdk.initialize(application: .shared, config: config)
} catch {
// handle errors
}
}
private fun changeDeviceLockRequired(context: Context) {
val config = XignSdkConfig.with { builder ->
builder.setKeyGenerationStrategy(
// one of `DeviceLockRequired.IGNORED/AUTOMATIC/REQUIRED`
deviceLockRequired = DeviceLockRequired.IGNORED
)
}
try {
XignSdk.initialize(context = context, config = config)
} catch (t: Throwable) {
// handle errors
}
}