在使用AndroidKeyStore生成RSA密鑰期間,我在我的應用程序中遇到了以下問題,而不是理解它可以輕鬆地在Android SDK的BasicAndroidKeyStore示例應用程序中再現。所以,如果你有Locale.getDefault() == Locale.US
比這個樣品效果很好,但如果你改變區域設置,例如,"ar_EG"
,它將與異常崩潰:AndroidKeyStore密鑰生成期間的IllegalArgumentException(Unparseable date)
java.lang.IllegalArgumentException異常:無效的日期字符串:無法解析 日期: 「af`cadaaedcaGMT + 00:00」(在偏移0) 在 com.android.org.bouncycastle.asn1.DERUTCTime(DERUTCTime.java:98) 在com.android.org.bouncycastle.asn1.x509。時間。(Time.java:62) at com.android.org.bouncycastle.x509.X509V3CertificateGenerator.setNotBefore(X509V3CertificateGenerator.java:112) 在 android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:127) 在 java.security.KeyPairGenerator $ KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:276) 在 com.example.android.basicandroidkeystore.BasicAndroidKeyStoreFragment.createKeys (BasicAndroidKeyStoreFragment.java:237)
所以,問題是在關鍵有效性時間轉換爲字符串,這是相對於默認的語言環境。 這裏是代碼段從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());
}
}
在調用給被傳遞到下面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));
}
那麼,什麼是正確的修復或建議如何解決這個問題?
1.什麼是Android版本,建設者號,和Android的機型你看到這個設備? 2.如果您在生成密鑰對和自簽名證書之前調用Locale.setDefault(Locale.US),問題是否消失? –
1.我在聯想A536(4.4.2)和LG Nexus 4(5.1.1)上對此進行了測試。 – texnedo
2.是的,我第一次發現這個問題後,試圖從代碼中改變語言環境。這個修復程序解決了這個問題,但它看起來很髒,因爲我們的應用程序的其他部分可能會調用Locale.getDefault()並獲取錯誤的值。 – texnedo