-
Notifications
You must be signed in to change notification settings - Fork 1
User authentication
CM SDK supports multiple means for user authentication. Application can use any of them, if it is supported by particular process or transaction. Currently, there are 3 types of user authentication:
- PIN - authentication with PIN (or password)
- Confirm - confirmation without user credentials
- Biometrics - authentication with user biometrics
In CM SDK different kinds of authentication are abstracted by Authentication interface/enum. Methods that require a user authentication will need an instance of any Authentication subclass / item of Authentication enum as one of the input parameters.
Android: If method requires specific type of user authentication, parameter is of the corresponding type.
interface CMAuthentication ...
class CMPinAuthentication : CMAuthentication ...
class CMConfirmAuthentication : CMAuthentication ...
class CMBiometricAuthentication : CMAuthentication ...iOS:
public enum Authentication {
case pin(pin: Data)
case confirm
case biometrics(prompt: String, biometricType: BiometricType = defaultBiometricType)
}Most basic user authentication in CM SDK is authentication with PIN, or generally, any form of password.
PinAuthentication class and Authentication.pin are simple wrappers of pin data. From plain value of user's PIN, application should derive some binary data. Anything from simple UTF-8 encoding to more complex derivation like hashing or PBKDF2 is acceptable. These data can be used to create an instance of PinAuthentication class or Authentication.pin enum item and use as an input to CM SDK methods.
Android:
val pinData: ByteArray = ... // derive value from user pin
val userAuth: CMAuthentication = CMPinAuthentication.instanceForPin(pinData)
// or
val userAuth: CMAuthentication = CMPinAuthentication(pinData)iOS:
let pinData: Data = ...//derive value from user pin
let userAuth = Authentication.pin(pin: pinData)Confirmation is not really an authentication. It represents user confirmation without authenticating himself. Nevertheless, confirmed transaction is still cryptographically signed on device and verified on server. Security of this kind of authentication is weak, therefore, it is disabled by default. For better user experience, it can be enabled for some types of transactions.
Android: To create ConfirmAuthentication instance no input from application is required.
val userAuth: CMAuthentication = CMConfirmAuthentication.instance
//or
val userAuth: CMAuthentication = CMConfirmAuthentication()iOS:
let userAuth = Authentication.confirmThe latest version of operating systems support also biometric authentication. CM SDK requires at least one of user's fingerprints (or face on iOS) to be enrolled in the device. Applications can authenticate user using enrolled fingers / face.
CASE is using biometric authentication as one of alternative authentications. Each alternative authentication method has a separate shared secret with CASE server and can be activated only after successful verification of PIN.
In CM SDK, biometrics authentication consists of a few related scenarios. Application can check if device supports biometric authentication, activate or deactivate biometrics authentication for particular account and create BiometricsAuthentication or Authentication.biometrics instance for methods that consume it.
To check if biometrics can be used on a particular device, following methods can be used.
On Android:
BiometricProperties(context).canAuthenticate() // see other methods for more informationOn iOS:
import CoreUtilities
let deviceBiometrics = DeviceBiometricsFactory.makeDeviceBiometrics()
deviceBiometrics.hasBiometryEnrolled()It checks:
- biometry is available (canEvaluatePolicy not returning error code LAError.biometryNotAvailable)
- enrolled fingerprints (canEvaluatePolicy not returning error code LAError.biometryNotEnrolled)
There are 2 ways to activate biometric authentication in CM SDK:
- during account activation
- in second mandatory step (confirm) application can specify what authentication method should be activated for newly created account
- additionally, for existing account
- start single step scenario, that contains verification of PIN after which it will activate biometric authentication
Android:
//1.
val requestedAuthMethods = EnumSet.of(..., CMAuthenticationMethod.Biometrics)
CMActivation.instance(context).confirm(..., requestedAuthMethods, ...)
//or
//2.
val userAuth: CMPinAuthentication = ...
val account: CMAccount = ...
account.activateBiometricAuthentication(context, userAuth, listener)iOS:
//1.
let requestedAuthenticationMethods: [AuthenticationMethod] = [..., .face /*or .fingerprint resolved by device hardware i.e. CoreUtilities*/]
Activation.instance().confirm(..., requestedAuthenticationMethods: requestedAuthenticationMethods, ...)
//or
//2.
let account: Account = ...
let pinData: Data = ...
let biometricType = BiometricType.face //or .fingerprint resolved by device hardware
account.activateBiometricAuthentication(pin: pinData, biometricType: biometricType, completion: completion)Deactivation will remove data related to biometric authentication from internal storage.
Android:
val account: CMAccount = ...
account.deactivateBiometricAuthentication(context)iOS:
let account: Account = ...
account.deactivateBiometricAuthentication()Wiping will replace users data with random data.
Usage of BiometricsAuthentication or Authentication.biometrics consists of few steps:
- Check if account has activated biometric authentication
- Create an instance of
BiometricsAuthenticationorAuthentication.biometrics - use instance to authenticate user (Android only), see google's documentation of particular API
- pass instance to CM SDK method
Android:
val account: CMAccount = ...
// 1.
val activated = account.isBiometricAuthenticationActivated(context)
// 2.
val bioAuth: CMBiometricAuthentication = account.getBiometricAuthentication(context)
// 3.
val biometricPrompt: BiometricPrompt = ...
val promptInfo: BiometricPrompt.PromptInfo = ...
val cryptoObject: BiometricPrompt.CryptoObject = bioAuth.getCryptoObjectForCompatBiometricPrompt()
biometricPrompt.authenticate(promptInfo, cryptoObject)
// 4.
val trx: CMTransaction = ...
trx.authorize(..., bioAuth, ...)iOS:
let account: Account = ...
// 1.
let activated = account.isBiometricAuthenticationActivated()
// 2.
let prompt: String = ...
let bioAuth = Authentication.biometrics(prompt: prompt)
// 4.
let transaction: Transaction = ...
transaction.authorize(authentication: bioAuth, completionHandler: completion)Continue to Transactions