55import android .security .KeyPairGeneratorSpec ;
66import android .security .keystore .KeyGenParameterSpec ;
77import android .security .keystore .KeyInfo ;
8+ import android .security .keystore .KeyNotYetValidException ;
89import android .security .keystore .KeyPermanentlyInvalidatedException ;
910import android .security .keystore .KeyProperties ;
11+ import android .security .keystore .UserNotAuthenticatedException ;
1012import android .util .Log ;
1113
1214import java .math .BigInteger ;
@@ -44,17 +46,12 @@ public static byte[] decrypt(byte[] encrypted, String alias) throws Exception {
4446
4547 public static void createKeyPair (Context ctx , String alias ) throws Exception {
4648 synchronized (LOCK ) {
47- Calendar notBefore = Calendar .getInstance ();
4849
49- //this back dates the date of the key in order to avoid some timezone issues found during use with some devices
50- notBefore .add (Calendar .HOUR_OF_DAY , -26 );
51- Calendar notAfter = Calendar .getInstance ();
52- notAfter .add (Calendar .YEAR , 100 );
5350 String principalString = String .format ("CN=%s, OU=%s" , alias , ctx .getPackageName ());
5451
55- if (Build .VERSION .SDK_INT > Build .VERSION_CODES .M ){
52+ if (Build .VERSION .SDK_INT > Build .VERSION_CODES .M ) {
5653 KeyPairGenerator generator = KeyPairGenerator .getInstance (KeyProperties .KEY_ALGORITHM_RSA , KEYSTORE_PROVIDER );
57- KeyGenParameterSpec .Builder builder = new KeyGenParameterSpec .Builder (alias , KeyProperties .PURPOSE_DECRYPT )
54+ KeyGenParameterSpec .Builder builder = new KeyGenParameterSpec .Builder (alias , KeyProperties .PURPOSE_DECRYPT | KeyProperties . PURPOSE_ENCRYPT )
5855 .setUserAuthenticationRequired (true )
5956 //the value used for the validity is 31 days a big number to ensure the keys are always usable after a authentication done by the user
6057 .setUserAuthenticationValidityDurationSeconds (60 *60 *24 *31 )
@@ -64,11 +61,7 @@ public static void createKeyPair(Context ctx, String alias) throws Exception {
6461 .setDigests (KeyProperties .DIGEST_SHA256 , KeyProperties .DIGEST_SHA512 )
6562 .setEncryptionPaddings (KeyProperties .ENCRYPTION_PADDING_RSA_PKCS1 )
6663 .setRandomizedEncryptionRequired (true )
67- .setKeyValidityStart (notBefore .getTime ())
68- .setKeyValidityEnd (notAfter .getTime ());
69- if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .N ){
70- builder .setInvalidatedByBiometricEnrollment (false );
71- }
64+ .setInvalidatedByBiometricEnrollment (false );
7265 KeyGenParameterSpec spec = builder .build ();
7366 generator .initialize (spec );
7467 generator .generateKeyPair ();
@@ -80,8 +73,6 @@ public static void createKeyPair(Context ctx, String alias) throws Exception {
8073 .setAlias (alias )
8174 .setSubject (new X500Principal (principalString ))
8275 .setSerialNumber (BigInteger .ONE )
83- .setStartDate (notBefore .getTime ())
84- .setEndDate (notAfter .getTime ())
8576 .setEncryptionRequired ()
8677 .setKeySize (2048 )
8778 .setKeyType ("RSA" )
@@ -90,8 +81,6 @@ public static void createKeyPair(Context ctx, String alias) throws Exception {
9081 kpGenerator .initialize (spec );
9182 kpGenerator .generateKeyPair ();
9283 }
93-
94-
9584 }
9685 }
9786
@@ -121,7 +110,7 @@ private static void initCipher(Cipher cipher, int cipherMode, String alias) thro
121110 }
122111 }
123112
124- public static boolean isEntryAvailable (String alias ) {
113+ public static boolean isEntryAvailable (String alias ) throws UserNotAuthenticatedException {
125114 KeyStore .PrivateKeyEntry entry ;
126115
127116 synchronized (LOCK ) {
@@ -141,6 +130,10 @@ public static boolean isEntryAvailable(String alias) {
141130 initCipher (tempCipher , Cipher .ENCRYPT_MODE , alias );
142131 initCipher (tempCipher , Cipher .DECRYPT_MODE , alias );
143132 return true ; // Key is usable
133+ } catch (UserNotAuthenticatedException e ) {
134+ throw e ;
135+ } catch (KeyNotYetValidException e ) {
136+ return false ;
144137 } catch (KeyPermanentlyInvalidatedException e ) {
145138 // Key is never usable again, so might as well consider it's not available
146139 // This will let a new one be used in its place
0 commit comments