无法在 Android 上创建密钥对
Can't create a KeyPair on Android
我正在玩转 android 中的密钥并尝试生成 public/private 密码 key-pair。不幸的是,我一直收到 'KeyStoreException: Invalid key blob'.
我正在按照此处的说明进行操作:
https://developer.android.com/training/articles/keystore.html
特别是标题为 'Generating a New Private Key' 的部分,我觉得我的代码几乎是逐字复制的:
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
keyGen.initialize(
new KeyGenParameterSpec.Builder(
keyName,
KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512).build()
);
KeyPair pair = keyGen.generateKeyPair();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
keyName
的值来自用户输入,但我也尝试过"abc"
。
我得到的错误是:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.calebg.claimcreator, PID: 17389
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access00(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access00(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: java.security.ProviderException: Failed to load generated key pair from keystore
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.loadKeystoreKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:530)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.generateKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:478)
at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:727)
at com.example.calebg.claimcreator.CreateKeyActivity.createKey(CreateKeyActivity.java:76)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access00(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: java.security.UnrecoverableKeyException: Failed to obtain X.509 form of public key
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:239)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:278)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:289)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.loadKeystoreKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:521)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.generateKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:478)
at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:727)
at com.example.calebg.claimcreator.CreateKeyActivity.createKey(CreateKeyActivity.java:76)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access00(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: android.security.KeyStoreException: Invalid key blob
at android.security.KeyStore.getKeyStoreException(KeyStore.java:823)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:241)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:278)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:289)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.loadKeystoreKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:521)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.generateKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:478)
at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:727)
at com.example.calebg.claimcreator.CreateKeyActivity.createKey(CreateKeyActivity.java:76)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access00(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
我正在使用 Android Studio 3.0.1,minSdkVersion 23,targetSdkVersion 26,我正在 "Nexus 6 API P" 虚拟设备上进行测试。
我发现的唯一其他相关的 Whosebug 问题(也是唯一的 google 结果)看起来有帮助:
但是我不清楚如何将答案应用于我的情况,并且我不相信它是我的情况下的正确解决方案(当我刚刚初始化时,密钥库怎么可能是 locked/uninitialised ? 捕获异常并重试如何解决这个问题?)。
谁能指出我做错了什么?
您可以试试下面的代码,它是基于 AES-128 加密算法的。
public void RandomKey(View view)
{
int[] Keys = new int[16];
String keyString ="";
//reset the secret key into null
Secret_Key="";
SecretKey.setText(Secret_Key);
try
{
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128); // 128 bit
javax.crypto.SecretKey secretKey = keyGen.generateKey(); //generate secret key
SKey= secretKey.getEncoded();
// to display
for (int i = 0; i < 16; i++)
{
Keys[i] = SKey[i] & 0x000000FF;//convert byte to integer
keyString = Integer.toHexString(Keys[i]);
if (keyString.length() < 2)
{
keyString="0"+keyString;
}
//Log.d("keys are"," "+i+keyString);
Secret_Key = Secret_Key + " " + keyString;
}
SecretKey.setAllCaps(true);
SecretKey.setText(Secret_Key);
}
更完整的程序可以参考这个:
https://github.com/aliakbarpa/AES-128_for_Android
我在真机上试过了,效果很好。不知道为什么,但出于某种原因,Android 模拟器无法根据 Android 文档创建密钥。
我在 Android-P 上尝试 运行 我的应用程序时遇到了同样的问题,我认为他们对密钥库进行了一些更改 See the preview,我想知道您的物理设备是否运行AndroidP?
我正在玩转 android 中的密钥并尝试生成 public/private 密码 key-pair。不幸的是,我一直收到 'KeyStoreException: Invalid key blob'.
我正在按照此处的说明进行操作:
https://developer.android.com/training/articles/keystore.html
特别是标题为 'Generating a New Private Key' 的部分,我觉得我的代码几乎是逐字复制的:
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore");
keyGen.initialize(
new KeyGenParameterSpec.Builder(
keyName,
KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
.setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512).build()
);
KeyPair pair = keyGen.generateKeyPair();
} catch (NoSuchProviderException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
keyName
的值来自用户输入,但我也尝试过"abc"
。
我得到的错误是:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.calebg.claimcreator, PID: 17389
java.lang.IllegalStateException: Could not execute method for android:onClick
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access00(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access00(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: java.security.ProviderException: Failed to load generated key pair from keystore
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.loadKeystoreKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:530)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.generateKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:478)
at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:727)
at com.example.calebg.claimcreator.CreateKeyActivity.createKey(CreateKeyActivity.java:76)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access00(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: java.security.UnrecoverableKeyException: Failed to obtain X.509 form of public key
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:239)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:278)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:289)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.loadKeystoreKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:521)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.generateKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:478)
at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:727)
at com.example.calebg.claimcreator.CreateKeyActivity.createKey(CreateKeyActivity.java:76)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access00(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
Caused by: android.security.KeyStoreException: Invalid key blob
at android.security.KeyStore.getKeyStoreException(KeyStore.java:823)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStorePublicKeyFromKeystore(AndroidKeyStoreProvider.java:241)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:278)
at android.security.keystore.AndroidKeyStoreProvider.loadAndroidKeyStoreKeyPairFromKeystore(AndroidKeyStoreProvider.java:289)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.loadKeystoreKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:521)
at android.security.keystore.AndroidKeyStoreKeyPairGeneratorSpi.generateKeyPair(AndroidKeyStoreKeyPairGeneratorSpi.java:478)
at java.security.KeyPairGenerator$Delegate.generateKeyPair(KeyPairGenerator.java:727)
at com.example.calebg.claimcreator.CreateKeyActivity.createKey(CreateKeyActivity.java:76)
at java.lang.reflect.Method.invoke(Native Method)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
at android.view.View.performClick(View.java:6579)
at android.view.View.performClickInternal(View.java:6556)
at android.view.View.access00(View.java:777)
at android.view.View$PerformClick.run(View.java:25660)
at android.os.Handler.handleCallback(Handler.java:819)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
我正在使用 Android Studio 3.0.1,minSdkVersion 23,targetSdkVersion 26,我正在 "Nexus 6 API P" 虚拟设备上进行测试。
我发现的唯一其他相关的 Whosebug 问题(也是唯一的 google 结果)看起来有帮助:
但是我不清楚如何将答案应用于我的情况,并且我不相信它是我的情况下的正确解决方案(当我刚刚初始化时,密钥库怎么可能是 locked/uninitialised ? 捕获异常并重试如何解决这个问题?)。
谁能指出我做错了什么?
您可以试试下面的代码,它是基于 AES-128 加密算法的。
public void RandomKey(View view)
{
int[] Keys = new int[16];
String keyString ="";
//reset the secret key into null
Secret_Key="";
SecretKey.setText(Secret_Key);
try
{
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128); // 128 bit
javax.crypto.SecretKey secretKey = keyGen.generateKey(); //generate secret key
SKey= secretKey.getEncoded();
// to display
for (int i = 0; i < 16; i++)
{
Keys[i] = SKey[i] & 0x000000FF;//convert byte to integer
keyString = Integer.toHexString(Keys[i]);
if (keyString.length() < 2)
{
keyString="0"+keyString;
}
//Log.d("keys are"," "+i+keyString);
Secret_Key = Secret_Key + " " + keyString;
}
SecretKey.setAllCaps(true);
SecretKey.setText(Secret_Key);
}
更完整的程序可以参考这个: https://github.com/aliakbarpa/AES-128_for_Android
我在真机上试过了,效果很好。不知道为什么,但出于某种原因,Android 模拟器无法根据 Android 文档创建密钥。
我在 Android-P 上尝试 运行 我的应用程序时遇到了同样的问题,我认为他们对密钥库进行了一些更改 See the preview,我想知道您的物理设备是否运行AndroidP?