com.ibm.security.access.mobile.authentication

Class KeyStoreHelper

  • java.lang.Object
    • com.ibm.security.access.mobile.authentication.KeyStoreHelper


  • public class KeyStoreHelper
    extends java.lang.Object
    The KeyStoreHelper class performs RSA export operations to DER and PEM formats that can be used outside of Android for data signing.
    Since:
    1.2.0
    Version:
    1.2.8
    Note:
    Due to a potential bug with the SHA512withRSA algorithm on a Nexus 5x with Android 6 https://code.google.com/p/android/issues/detail?id=210237, we use SHA256withRSA
    • Constructor Summary

      Constructors 
      Constructor and Description
      KeyStoreHelper() 
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method and Description
      boolean checkKeyPairExists(java.lang.String keyName)
      Returns true if the keystore could be loaded and a key with keyName found.
      void createKeyPair(java.lang.String keyName, boolean authenticationRequired, IKeyStoreHelperCallbackHandleResult callback)
      Generates a private and public key to sign data.
      static void deleteKeyPair(java.lang.String keyName, IKeyStoreHelperCallbackHandleDelKeyPair callback)
      Delete a private and public key from the KeyStore.
      static java.lang.String exportPublicKey(java.lang.String keyName)
      Returns the public key retrieved from the keystore in Privacy Enhanced Mail (PEM) format.
      static java.lang.String exportPublicKey(java.lang.String keyName, int base64EncodingOptions)
      Returns the public key retrieved from the keystore in Privacy Enhanced Mail (PEM) format.
      static java.lang.String getKeystoreType()
      Returns the type of keystore.
      static java.lang.String getSignatureAlgorithm()
      Returns the standard name of the algorithm requested
      static boolean hasAuthenticationSettingsChanged(java.lang.String keyNameForChangeCheck)
      Checks if the authentication settings have changed since the key was created.
      java.lang.String signData(android.hardware.fingerprint.FingerprintManager.AuthenticationResult authenticationResult, java.lang.String value, int base64EncodingOptions)
      Using an authorozed key generated by the device to sign the value and return the encrypted result.
      static java.lang.String signData(java.lang.String keyName, java.lang.String value)
      Using a key generated by the device to sign the value and return the encrypted result.
      static java.lang.String signData(java.lang.String keyName, java.lang.String value, int base64EncodingOptions)
      Using a key generated by the device to sign the value and return the encrypted result.
      • Methods inherited from class java.lang.Object

        equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • KeyStoreHelper

        public KeyStoreHelper()
    • Method Detail

      • getKeystoreType

        public static java.lang.String getKeystoreType()
        Returns the type of keystore.
        Returns:
        the type of keystore
        Since:
        1.2.5
      • getSignatureAlgorithm

        public static java.lang.String getSignatureAlgorithm()
        Returns the standard name of the algorithm requested
        Returns:
        the standard name of the algorithm requested
        Since:
        1.2.5
      • exportPublicKey

        public static java.lang.String exportPublicKey(java.lang.String keyName)
        Returns the public key retrieved from the keystore in Privacy Enhanced Mail (PEM) format.
        Parameters:
        keyName - the unique identifier of the tenant and the type of IEnrollment
        Returns:
        Privacy Enhanced Mail (PEM) representation of the key in Base64.DEFAULT encoding
      • exportPublicKey

        public static java.lang.String exportPublicKey(java.lang.String keyName,
                                                       int base64EncodingOptions)
        Returns the public key retrieved from the keystore in Privacy Enhanced Mail (PEM) format.
        Parameters:
        keyName - the unique identifier of the tenant and the type of IEnrollment
        base64EncodingOptions - the flag controls certain features of the encoded output
        Returns:
        Privacy Enhanced Mail (PEM) representation of the key
        Since:
        1.2.4
      • createKeyPair

        public void createKeyPair(java.lang.String keyName,
                                  boolean authenticationRequired,
                                  IKeyStoreHelperCallbackHandleResult callback)
        Generates a private and public key to sign data. An existing key pair with same alias will be deleted.
        Parameters:
        keyName - the unique identifier of the tenant and the type of IEnrollment
        authenticationRequired - indicates whether the generated key requires authentication (fingerprint) in order to get access to it. Only valid if API level >= 23.
        callback - the function delegate that is invoked with the PublicKey
        Note:
        the keys are automatically stored in key store which comprises of tenantId.enrollment.type. The size is 2,048 bits.

        For API level >= 23: the key is valid for 10 years. See also KeyPairGeneratorSpec.getEndDate()

      • deleteKeyPair

        public static void deleteKeyPair(java.lang.String keyName,
                                         IKeyStoreHelperCallbackHandleDelKeyPair callback)
        Delete a private and public key from the KeyStore.
        Parameters:
        keyName - the unique identifier of the tenant and the type of IEnrollment
        callback - the function delegate that is invoked with the success flag indicate if the key pair has been deleted
      • signData

        public static java.lang.String signData(java.lang.String keyName,
                                                java.lang.String value)
        Using a key generated by the device to sign the value and return the encrypted result.
        Parameters:
        keyName - the unique identifier of the tenant and the type of IEnrollment
        value - the string to encrypt
        Returns:
        the base64 signed data or null if the value can not be signed
      • signData

        public static java.lang.String signData(java.lang.String keyName,
                                                java.lang.String value,
                                                int base64EncodingOptions)
        Using a key generated by the device to sign the value and return the encrypted result.
        Parameters:
        keyName - the unique identifier of the tenant and the type of IEnrollment
        value - the string to encrypt
        base64EncodingOptions - the flag controls certain features of the encoded output
        Returns:
        the base64 signed data or null if the value can not be signed
        Since:
        1.2.4
      • signData

        public java.lang.String signData(android.hardware.fingerprint.FingerprintManager.AuthenticationResult authenticationResult,
                                         java.lang.String value,
                                         int base64EncodingOptions)
        Using an authorozed key generated by the device to sign the value and return the encrypted result.
        Parameters:
        authenticationResult - the FingerprintManager.AuthenticationResult instance that holds the authorized key for the signing
        value - the string to encrypt
        base64EncodingOptions - the flag controls certain features of the encoded output
        Returns:
        the base64 signed data or null if the value can not be signed
        Since:
        1.2.5
      • hasAuthenticationSettingsChanged

        public static boolean hasAuthenticationSettingsChanged(java.lang.String keyNameForChangeCheck)
        Checks if the authentication settings have changed since the key was created. It uses the occurance of a KeyPermanentlyInvalidatedException as an indication whether the user has done one of the following:
        • added another fingerprint
        • removed all fingerprints
        • disabled the secure lock screen
        • the secure lock screen has been forcibely reseted

        As decribed here, that will irreversibly invalidate keys. The key to check should be created with the following settings:
        • KeyProperties#PURPOSE_SIGN
        • KeyGenParameterSpec.Builder#setUserAuthenticationRequired(boolean) as true
        • KeyGenParameterSpec.Builder#setUserAuthenticationValidityDurationSeconds(int) as -1
        • KeyGenParameterSpec.Builder#setInvalidatedByBiometricEnrollment(boolean) as true

        createKeyPair(String, boolean, IKeyStoreHelperCallbackHandleResult) will create a key that fulfills these requirements.

        The observed behaviour through testing is not in line with the documentation here. Apparently the key gets only permanently invalidated when a fingerprint is added, but not when all fingerprints have been removed nor when the Secure Lock Screen has been disabled. As long as this state remains, these settings can be checked with isDeviceSecure and hasEnrolledFingerprint.

        Parameters:
        keyNameForChangeCheck - the name of the key used for the checking.
        Returns:
        true if the key could be found in the keystore and the user has done one of the actions mentioned above since the key was created and Android API >= 23
        false otherwise
        Since:
        1.2.5
      • checkKeyPairExists

        public boolean checkKeyPairExists(java.lang.String keyName)
        Returns true if the keystore could be loaded and a key with keyName found.
        Parameters:
        keyName - the unique identifier of the key.
        Returns:
        true if the key with keyName exists
        false otherwise