22
33import android .annotation .TargetApi ;
44import android .content .Context ;
5+ import android .content .res .Configuration ;
6+ import android .content .res .Resources ;
57import android .os .Build ;
68import android .security .keystore .KeyGenParameterSpec ;
79import android .security .keystore .KeyProperties ;
2426import java .security .spec .InvalidKeySpecException ;
2527import java .security .spec .MGF1ParameterSpec ;
2628import java .security .spec .X509EncodedKeySpec ;
29+ import java .util .Locale ;
2730
2831import javax .crypto .BadPaddingException ;
2932import javax .crypto .Cipher ;
@@ -109,10 +112,6 @@ private boolean generateKeyIfNecessary(@NonNull Context context, @NonNull KeySto
109112 return false ;
110113 }
111114
112- private boolean generateKey (Context context , String keystoreAlias , boolean isAuthenticationRequired ) {
113- return generateKey (keystoreAlias , isAuthenticationRequired );
114- }
115-
116115 private String decode (String encodedString , Cipher cipher ) throws PFSecurityException {
117116 try {
118117 final byte [] bytes = Base64 .decode (encodedString , Base64 .NO_WRAP );
@@ -143,8 +142,14 @@ public String decode(String alias, String encodedString) throws PFSecurityExcept
143142 }
144143
145144 @ TargetApi (Build .VERSION_CODES .M )
146- private boolean generateKey (String keystoreAlias , boolean isAuthenticationRequired ) {
145+ private boolean generateKey (Context context , String keystoreAlias , boolean isAuthenticationRequired ) {
147146 try {
147+ // Set English locale as default (workaround for rtl parsing date exception)
148+ // From https://stackoverflow.com/a/46602170
149+ // FIXME: A temporary fixture for issue described at https://issuetracker.google.com/issues/37095309
150+ Locale initialLocale = Locale .getDefault ();
151+ setLocale (context , Locale .ENGLISH );
152+
148153 final KeyPairGenerator keyGenerator = KeyPairGenerator .getInstance (
149154 KeyProperties .KEY_ALGORITHM_RSA , "AndroidKeyStore" );
150155 keyGenerator .initialize (
@@ -156,6 +161,8 @@ private boolean generateKey(String keystoreAlias, boolean isAuthenticationRequir
156161 .setUserAuthenticationRequired (isAuthenticationRequired )
157162 .build ());
158163 keyGenerator .generateKeyPair ();
164+ // Reset default locale
165+ setLocale (context , initialLocale );
159166 return true ;
160167
161168 } catch ( NoSuchAlgorithmException
@@ -166,6 +173,14 @@ private boolean generateKey(String keystoreAlias, boolean isAuthenticationRequir
166173 }
167174 }
168175
176+ private void setLocale (Context context , Locale locale ) {
177+ Locale .setDefault (locale );
178+ Resources resources = context .getResources ();
179+ Configuration config = resources .getConfiguration ();
180+ config .locale = locale ;
181+ resources .updateConfiguration (config , resources .getDisplayMetrics ());
182+ }
183+
169184 private Cipher getCipherInstance () throws PFSecurityException {
170185 try {
171186 final Cipher cipher = Cipher .getInstance ("RSA/ECB/OAEPWithSHA-256AndMGF1Padding" );
0 commit comments