我在使用AndroidKeyStore生成RSA密钥期间在我的应用程序中遇到了以下问题,而不是理解它可以在Android SDK的BasicAndroidKeyStore示例应用程序中轻松复制。因此,如果您的Locale.getDefault() == Locale.US
比此示例效果良好,但如果您将语言环境更改为"ar_EG"
,则会因异常而崩溃:
java.lang.IllegalArgumentException:无效的日期字符串:Unparseable 日期:" af`cadaaedcaGMT + 00:00" (在偏移0处) 在 com.android.org.bouncycastle.asn1.DERUTCTime。(DERUTCTime.java:98) 在com.android.org.bouncycastle.asn1.x509.Time。(Time.java:62) 在 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)
因此,问题在于转换为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));
}
那么,什么是正确的解决方案或建议如何解决这个问题?
答案 0 :(得分:5)
这是known issue with AndroidKeyStore。
Android KeyStore没有正确接受语言环境,并且它会导致设备语言环境的失败,语言从右到左。样本堆栈跟踪:
import cv2
import numpy as np
#Created an image (really an ndarray) with three channels
new_image = np.ndarray((3, num_rows, num_cols), dtype=int)
#Did manipulations for my project where my array values went way over 255
#Eventually returned numbers to between 0 and 255
#Converted the datatype to np.uint8
new_image = new_image.astype(np.uint8)
#Separated the channels in my new image
new_image_red, new_image_green, new_image_blue = new_image
#Stacked the channels
new_rgb = np.dstack([new_image_red, new_image_green, new_image_blue])
#Displayed the image
cv2.imshow("WindowNameHere", new_rgbrgb)
cv2.waitKey(0)
解决方法是在生成密钥对之前设置英语区域设置并将其更改回来:
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)
答案 1 :(得分:0)
我在Android M中使用以下代码生成RSA密钥对。可能会帮助您。
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA",
"AndroidKeyStore");
gen.initialize(new KeyGenParameterSpec.Builder(KEY_ALIAS,
KeyProperties.PURPOSE_ENCRYPT
| KeyProperties.PURPOSE_DECRYPT)
.setDigests(KeyProperties.DIGEST_SHA256,
KeyProperties.DIGEST_SHA512)
.setSignaturePaddings(
KeyProperties.SIGNATURE_PADDING_RSA_PSS)
.setEncryptionPaddings(
KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
.build());
KeyPair keyPair = gen.generateKeyPair();
答案 2 :(得分:0)
1- 将计算机的日期和时间设置为默认设置
2- 为您所在地区设置正确的时区
3- 重启安卓工作室