Android密钥库错误“无法在密钥库中生成密钥”

尝试为某些设备生成密钥时出现错误。 我能够在运行4.4.2的Samsung Galaxy Note上重现错误。

java.lang.IllegalStateException: could not generate key in keystore at android.security.AndroidKeyPairGenerator.generateKeyPair(AndroidKeyPairGenerator.java:100) at java.security.KeyPairGenerator$KeyPairGeneratorImpl.generateKeyPair(KeyPairGenerator.java:275) at com.eric.demo.MainActivity.generateKeyPair(MainActivity.java:65) at com.eric.demo.MainActivity.onClickButton(MainActivity.java:43) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at android.view.View$1.onClick(View.java:3964) at android.view.View.performClick(View.java:4640) at android.view.View$PerformClick.run(View.java:19421) at android.os.Handler.handleCallback(Handler.java:733) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5476) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084) at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:132) at dalvik.system.NativeStart.main(Native Method) 

我创build了一个小应用程序,通过从Android开发者页面https://developer.android.com/training/articles/keystore.html的 “生成新的私钥”下面逐行复制代码来生成密钥。

  public void onClickButton (View view) { try { generateKeyPair(this, "test3"); } catch (Exception e){ Log.wtf("exception", e); } } private void generateKeyPair(Context context, String alias) throws Exception { Calendar cal = Calendar.getInstance(); Date now = cal.getTime(); cal.add(Calendar.YEAR, 1); Date end = cal.getTime(); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore"); kpg.initialize(new KeyPairGeneratorSpec.Builder(getApplicationContext()) .setAlias(alias) .setStartDate(now) .setEndDate(end) .setSerialNumber(BigInteger.valueOf(1)) .setSubject(new X500Principal("CN=test3")) .build()); KeyPair kp = kpg.generateKeyPair(); } 

该错误似乎发生在AndroidKeyPairGenerator.java内部的kpg.generateKeyPair()中:

 if (!mKeyStore.generate(privateKeyAlias, KeyStore.UID_SELF, keyType, mSpec.getKeySize(), mSpec.getFlags(), args)) { throw new IllegalStateException("could not generate key in keystore"); } 

并在KeyStore.java中:

 public boolean generate(String key, int uid, int keyType, int keySize, int flags, byte[][] args) { try { return mBinder.generate(key, uid, keyType, keySize, flags, args) == NO_ERROR; } catch (RemoteException e) { Log.w(TAG, "Cannot connect to keystore", e); return false; } } 

mBinder.generate()调用似乎返回2这意味着密钥库被locking?

 // ResponseCodes public static final int NO_ERROR = 1; public static final int LOCKED = 2; public static final int UNINITIALIZED = 3; public static final int SYSTEM_ERROR = 4; public static final int PROTOCOL_ERROR = 5; public static final int PERMISSION_DENIED = 6; public static final int KEY_NOT_FOUND = 7; public static final int VALUE_CORRUPTED = 8; public static final int UNDEFINED_ACTION = 9; public static final int WRONG_PASSWORD = 10; 

这个错误可能与这个问题有一定的关系:https://code.google.com/p/android/issues/detail? id = 177459 & q = could%20not%20generate%20key%20in%20keystore & colspec = ID% 20Type% 20Status%20Owner%20Summary%20Stars

我已经单独尝试了几件事情,并结合以下内容:
1.设置所需的encryption。 结果是另一个错误:“如果需要encryption,Android密钥库必须处于初始化和解锁状态”
2.设置locking屏幕(图案,PIN,无,密码,滑动)。 同样的行为
3.以编程方式尝试使用startActivity(new Intent("com.android.credentials.UNLOCK"));解锁或重置凭证存储startActivity(new Intent("com.android.credentials.UNLOCK")); 或者startActivity(new Intent("com.android.credentials.RESET")); 试图解锁显示“input密码的凭据存储”消息,其中没有合理的密码工作,甚至清除凭据没有帮助。

虽然我不知道完整的答案,但我可以帮助您继续search。 mBinder另一端的binder实现是本地密钥库 。 如果我完全记得,它的行为是1)支持软件级别的关键操作,或者2)委托给OEM提供的密钥库(可能)与OEM的硬件支持的密钥库接口。 更多信息在这里 , 在这里 , 这里 。

注意:因为我将三篇文章都链接到了大于1页的页面,而且发布了6页的答案似乎有点荒谬,所以我会放弃SO的常规策略:将外部链接内容拉入答案中; )

如果您的代码是确定的,请记住您需要为您的设备设置PIN / PW /指纹(安全解锁),以便密钥库开始运行。 如果你尝试生成密钥对,简单的刷卡就会出现这样的错误。

我认为这是正确的方向:右键单击项目> Android工具>导出签名的应用程序包出现导出Android应用程序向导。 select我想要导出的项目,点击下一步。 出现密钥库select屏幕。