
我在使用AndroidKeyStore生成RSA密钥期间在应用程序中遇到了以下问题,而不是理解它可以在AndroID SDK的BasicAndroIDKeyStore示例应用程序中轻松复制.因此,如果您的Locale.getDefault()== Locale.US比此示例效果好,但如果您将语言环境更改为“ar_EG”,则会因异常而崩溃:
java.lang.IllegalArgumentException: invalID date string: Unparseable
date: “af`cadaaedcaGMT+00:00” (at offset 0)
at
com.androID.org.bouncycastle.asn1.DERUTCTime.(DERUTCTime.java:98)
at com.androID.org.bouncycastle.asn1.x509.Time.(Time.java:62)
at
com.androID.org.bouncycastle.x509.X509V3CertificateGenerator.setNotBefore(X509V3CertificateGenerator.java:112)
at
androID.security.AndroIDKeyPairGenerator.generateKeyPair(AndroIDKeyPairGenerator.java:127)
at
java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:276)
at
com.example.androID.basicandroIDkeystore.BasicAndroIDKeyStoreFragment.createKeys(BasicAndroIDKeyStoreFragment.java:237)
因此,问题在于转换为String的密钥有效时间,该字符串是针对默认语言环境进行的.
这是来自ASN1UTCTime类的代码片段,它在KeyPairGenerator.generateKeyPair()的引擎下使用,方法调用:
public ASN1UTCTime( String time){ this.time = Strings.toByteArray(time); try { this.getDate(); } catch (ParseException e) { throw new IllegalArgumentException("invalID date string: " + e.getMessage()); }}在调用此方法之前,Date对象将传递给以下Time构造函数,该构造函数使用默认系统区域设置:
public Time( Date time) { SimpleTimeZone tz = new SimpleTimeZone(0, "Z"); SimpleDateFormat dateF = new SimpleDateFormat("yyyyMMddHHmmss"); dateF.setTimeZone(tz); String d = dateF.format(time) + "Z"; int year = Integer.parseInt(d.substring(0, 4)); if (year < 1950 || year > 2049) { this.time = new DERGeneralizedTime(d); } else { this.time = new DERUTCTime(d.substring(2)); } } 这很奇怪,因为ASN1UTCTime类有另一个构造函数,这似乎更适合国际工作:
/** * Base constructor from a java.util.date and Locale - you may need to use this if the default locale * doesn't use a Gregorian calender so that the GeneralizedTime produced is compatible with other ASN.1 implementations. * * @param time a date object representing the time of interest. * @param locale an appropriate Locale for producing an ASN.1 UTCTime value. */ public ASN1UTCTime( Date time, Locale locale) { SimpleDateFormat dateF = new SimpleDateFormat("yyMMddHHmmss'Z'", locale); dateF.setTimeZone(new SimpleTimeZone(0,"Z")); this.time = Strings.toByteArray(dateF.format(time)); } 那么,什么是正确的解决方案或建议如何解决这个问题?
解决方法:
这是一个known issue with AndroidKeyStore.
AndroID KeyStore没有正确接受语言环境,它会导致设备语言环境的失败,语言从右到左.样本堆栈跟踪:
Caused by: java.lang.IllegalArgumentException: invalID date string: Unparseable date: "aga``eaeeb`eGMT+00:00" (at offset 0) at com.androID.org.bouncycastle.asn1.DERUTCTime.<init>(DERUTCTime.java:98) at com.androID.org.bouncycastle.asn1.x509.Time.<init>(Time.java:62) at com.androID.org.bouncycastle.x509.X509V3CertificateGenerator.setNotBefore(X509V3CertificateGenerator.java:112) at androID.security.AndroIDKeyPairGenerator.generateKeyPair(AndroIDKeyPairGenerator.java:128) at java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:275)解决方法是在生成密钥对之前设置英语区域设置并在之后将其更改回来:
/** * Generates RSA keys. */private voID generateRsaKeys(Context context, String rsaAlias) { try { // Set English locale as default (workaround) Locale initialLocale = Locale.getDefault(); setLocale(Locale.ENGliSH); // Generate the RSA key pairs Calendar start = Calendar.getInstance(); Calendar end = Calendar.getInstance(); end.add(Calendar.YEAR, 30); // 30 years KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context) .setAlias(rsaAlias) .setSubject(new X500Principal("CN=" + rsaAlias + ", O=Organization")) .setSerialNumber(BigInteger.TEN) .setStartDate(start.getTime()) .setEndDate(end.getTime()) .build(); KeyPairGenerator kpg = KeyPairGenerator.getInstance(RSA, ANDROID_KEY_STORE); kpg.initialize(spec); kpg.generateKeyPair(); // reset default locale setLocale(initialLocale); } catch (NoSuchAlgorithmException | NoSuchProvIDerException | InvalIDAlgorithmParameterException e) { Log.e(e, "generateRsaKeys: "); }}/** * Sets default locale. */private voID setLocale(Locale locale) { Locale.setDefault(locale); Resources resources = context.getResources(); Configuration config = resources.getConfiguration(); config.locale = locale; resources.updateConfiguration(config, resources.getdisplayMetrics());} 总结 以上是内存溢出为你收集整理的java – 在AndroidKeyStore密钥生成期间出现IllegalArgumentException(Unparseable date)全部内容,希望文章能够帮你解决java – 在AndroidKeyStore密钥生成期间出现IllegalArgumentException(Unparseable date)所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)