API21 中生成密钥对时无法生成证书异常
Can't Generate Certificate Exception When Generating Key Pair In API 21
我一直在尝试解决这个只发生在 Android Lollipop (API 21) 中的异常。我试图寻找其他解决方案,但唯一相关的是 Generate KeyPair with KeyPairGeneratorSpec on API < 23,建议的解决方案无效。
我错过了什么吗?谢谢!
这是我在最后一行抛出的代码:
Calendar start = Calendar.getInstance();
Calendar end = Calendar.getInstance();
end.add(Calendar.YEAR, 30);
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(appContext)
.setAlias(getSecureSettingsKeyAlias())
.setSubject(new X500Principal("CN=" + getSecureSettingsKeyAlias()))
.setSerialNumber(BigInteger.TEN)
.setStartDate(start.getTime())
.setEndDate(end.getTime())
.build();
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, AndroidKeyStore);
kpg.initialize(spec);
kpg.generateKeyPair();
这是正在发生的异常:
Caused by: java.lang.IllegalStateException: Can't generate certificate
at android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:136)
at java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:276)
at com.sampleid.sampleid_sdk.common.FileSettingsStorage.getKeystore(FileSettingsStorage.java:302)
at com.sampleid.sampleid_sdk.common.FileSettingsStorage.writeSecureSettings(FileSettingsStorage.java:185)
at com.sampleid.sampleid_sdk.common.SettingsImpl.saveSecureSettings(SettingsImpl.java:473)
at com.sampleid.sampleid_sdk.common.SettingsImpl.saveSettings(SettingsImpl.java:321)
at com.sampleid.sampleid_sdk.sampleIDService.saveSettingsToStorage(sampleIDService.java:102)
at com.sampleid.sampleid_sdk.sampleIDService.saveSettings(sampleIDService.java:91)
at com.sampleid.sampleid.features.shared.BaseActivity.onStop(BaseActivity.java:182)
at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1261)
at android.app.Activity.performStop(Activity.java:6089)
at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3341)
at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3390)
at android.app.ActivityThread.access00(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.UnsupportedOperationException: private exponent cannot be extracted
at com.android.org.conscrypt.OpenSSLRSAPrivateKey.getPrivateExponent(OpenSSLRSAPrivateKey.java:161)
at org.spongycastle.jcajce.provider.asymmetric.rsa.RSAUtil.generatePrivateKeyParameter(RSAUtil.java:63)
at org.spongycastle.jcajce.provider.asymmetric.rsa.DigestSignatureSpi.engineInitSign(DigestSignatureSpi.java:95)
at java.security.Signature$SignatureImpl.engineInitSign(Signature.java:679)
at java.security.Signature.initSign(Signature.java:330)
at com.android.org.bouncycastle.x509.X509Util.calculateSignature(X509Util.java:243)
at com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(X509V3CertificateGenerator.java:434)
at com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(X509V3CertificateGenerator.java:412)
at android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:133)
at java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:276)
at com.sampleid.sampleid_sdk.common.FileSettingsStorage.getKeystore(FileSettingsStorage.java:302)
at com.sampleid.sampleid_sdk.common.FileSettingsStorage.writeSecureSettings(FileSettingsStorage.java:185)
at com.sampleid.sampleid_sdk.common.SettingsImpl.saveSecureSettings(SettingsImpl.java:473)
at com.sampleid.sampleid_sdk.common.SettingsImpl.saveSettings(SettingsImpl.java:321)
at com.sampleid.sampleid_sdk.sampleIDService.saveSettingsToStorage(sampleIDService.java:102)
at com.sampleid.sampleid_sdk.sampleIDService.saveSettings(sampleIDService.java:91)
at com.sampleid.sampleid.features.shared.BaseActivity.onStop(BaseActivity.java:182)
at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1261)
at android.app.Activity.performStop(Activity.java:6089)
at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3341)
at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3390)
at android.app.ActivityThread.access00(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
终于解决了。问题出在以下方面:
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, AndroidKeyStore);
KeyProperties.KEY_ALGORITHM_RSA
仅在 API 23 开始可用,因此在此之前的 API 秒内失败。将其替换为 "RSA"
此外,如果您使用的是 SpongyCastle,则应使用以下方法添加它:
static {
// as per https://github.com/rtyley/spongycastle/issues/27
Security.addProvider(new org.spongycastle.jce.provider.BouncyCastleProvider());
}
我一直在尝试解决这个只发生在 Android Lollipop (API 21) 中的异常。我试图寻找其他解决方案,但唯一相关的是 Generate KeyPair with KeyPairGeneratorSpec on API < 23,建议的解决方案无效。
我错过了什么吗?谢谢!
这是我在最后一行抛出的代码:
Calendar start = Calendar.getInstance();
Calendar end = Calendar.getInstance();
end.add(Calendar.YEAR, 30);
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(appContext)
.setAlias(getSecureSettingsKeyAlias())
.setSubject(new X500Principal("CN=" + getSecureSettingsKeyAlias()))
.setSerialNumber(BigInteger.TEN)
.setStartDate(start.getTime())
.setEndDate(end.getTime())
.build();
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, AndroidKeyStore);
kpg.initialize(spec);
kpg.generateKeyPair();
这是正在发生的异常:
Caused by: java.lang.IllegalStateException: Can't generate certificate
at android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:136)
at java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:276)
at com.sampleid.sampleid_sdk.common.FileSettingsStorage.getKeystore(FileSettingsStorage.java:302)
at com.sampleid.sampleid_sdk.common.FileSettingsStorage.writeSecureSettings(FileSettingsStorage.java:185)
at com.sampleid.sampleid_sdk.common.SettingsImpl.saveSecureSettings(SettingsImpl.java:473)
at com.sampleid.sampleid_sdk.common.SettingsImpl.saveSettings(SettingsImpl.java:321)
at com.sampleid.sampleid_sdk.sampleIDService.saveSettingsToStorage(sampleIDService.java:102)
at com.sampleid.sampleid_sdk.sampleIDService.saveSettings(sampleIDService.java:91)
at com.sampleid.sampleid.features.shared.BaseActivity.onStop(BaseActivity.java:182)
at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1261)
at android.app.Activity.performStop(Activity.java:6089)
at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3341)
at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3390)
at android.app.ActivityThread.access00(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.UnsupportedOperationException: private exponent cannot be extracted
at com.android.org.conscrypt.OpenSSLRSAPrivateKey.getPrivateExponent(OpenSSLRSAPrivateKey.java:161)
at org.spongycastle.jcajce.provider.asymmetric.rsa.RSAUtil.generatePrivateKeyParameter(RSAUtil.java:63)
at org.spongycastle.jcajce.provider.asymmetric.rsa.DigestSignatureSpi.engineInitSign(DigestSignatureSpi.java:95)
at java.security.Signature$SignatureImpl.engineInitSign(Signature.java:679)
at java.security.Signature.initSign(Signature.java:330)
at com.android.org.bouncycastle.x509.X509Util.calculateSignature(X509Util.java:243)
at com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(X509V3CertificateGenerator.java:434)
at com.android.org.bouncycastle.x509.X509V3CertificateGenerator.generate(X509V3CertificateGenerator.java:412)
at android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:133)
at java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:276)
at com.sampleid.sampleid_sdk.common.FileSettingsStorage.getKeystore(FileSettingsStorage.java:302)
at com.sampleid.sampleid_sdk.common.FileSettingsStorage.writeSecureSettings(FileSettingsStorage.java:185)
at com.sampleid.sampleid_sdk.common.SettingsImpl.saveSecureSettings(SettingsImpl.java:473)
at com.sampleid.sampleid_sdk.common.SettingsImpl.saveSettings(SettingsImpl.java:321)
at com.sampleid.sampleid_sdk.sampleIDService.saveSettingsToStorage(sampleIDService.java:102)
at com.sampleid.sampleid_sdk.sampleIDService.saveSettings(sampleIDService.java:91)
at com.sampleid.sampleid.features.shared.BaseActivity.onStop(BaseActivity.java:182)
at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1261)
at android.app.Activity.performStop(Activity.java:6089)
at android.app.ActivityThread.performStopActivityInner(ActivityThread.java:3341)
at android.app.ActivityThread.handleStopActivity(ActivityThread.java:3390)
at android.app.ActivityThread.access00(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1307)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
终于解决了。问题出在以下方面:
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, AndroidKeyStore);
KeyProperties.KEY_ALGORITHM_RSA
仅在 API 23 开始可用,因此在此之前的 API 秒内失败。将其替换为 "RSA"
此外,如果您使用的是 SpongyCastle,则应使用以下方法添加它:
static {
// as per https://github.com/rtyley/spongycastle/issues/27
Security.addProvider(new org.spongycastle.jce.provider.BouncyCastleProvider());
}