赞
踩
我试图使用此要点对我的应用程序中的某些数据进行加密。
我用我的别名" Pablo"签署了apk。
问题是尝试运行此代码:
public static String encrypt(String alias, String plaintext) {
try {
PublicKey publicKey = getPrivateKeyEntry(alias).getCertificate().getPublicKey();
Cipher cipher = getCipher();
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return Base64.encodeToString(cipher.doFinal(plaintext.getBytes()), Base64.NO_WRAP);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static KeyStore.PrivateKeyEntry getPrivateKeyEntry(String alias) {
try {
KeyStore ks = KeyStore
.getInstance("AndroidKeyStore");
ks.load(null);
KeyStore.Entry entry = ks.getEntry(alias, null);
if (entry == null) {
Log.w(TAG,"No key found under alias:" + alias);
Log.w(TAG,"Exiting signData()...");
return null;
}
if (!(entry instanceof KeyStore.PrivateKeyEntry)) {
Log.w(TAG,"Not an instance of a PrivateKeyEntry");
Log.w(TAG,"Exiting signData()...");
return null;
}
return (KeyStore.PrivateKeyEntry) entry;
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
return null;
}
}
但是我得到了一个例外:"别名下找不到密钥"
任何想法? 我必须输入与我的jks相同的别名吗?
谢谢!
您是否尝试在命令行上列出密钥库别名?stackoverflow.com/a/12894334/1056359
是的,别名可以,我在带签名的apk的调试中尝试
在哪行代码中发生异常? 确保从运行应用程序的jre使用正确的密钥库。 使用的运行时JRE可以是一个不同的运行时JRE,其中包含另一个没有别名的密钥库。
在这部分代码中:KeyStore.Entry entry = ks.getEntry(alias,null);
我尝试获取发布apk并使用adb工具在我的设备上运行它,得到同样的错误
Sonic的答案是正确的,因为您用来对应用程序进行签名的Java密钥存储区与您在应用程序中使用的密钥存储区不同。前者是您的开发机器(笔记本电脑)上的文件,而后者仅在您将应用程序安装到的手机(Android手机或模拟器)上。对您的apk进行签名以使其可以在Play商店中发布,并对数据中的用户私人数据进行加密是不同的过程。
在不清楚的情况下,您应该尝试参考规范的资源,而不是质量差异很大的专断依据和教程。在这种情况下,KeyStore的官方Android文档提供了存储密钥的完整示例。请注意,Gist中引用的Android KeyStore仅在API 18+上可用。
诚然,官方文档和Gist中的代码示例非常复杂,很容易出错。更好的选择可能是使用Scytale之类的东西。它是KeyStore的包装,可以正确处理API <18的情况。下面的代码段演示:
Store store = new Store(getApplicationContext());
if (!store.hasKey("test")) {
SecretKey key = store.generateSymmetricKey("test", null);
}
...
// Get key
SecretKey key = store.getSymmetricKey("test", null);
// Encrypt/Decrypt data
Crypto crypto = new Crypto(Options.TRANSFORMATION_SYMMETRIC);
String text ="Sample text";
String encryptedData = crypto.encrypt(text, key);
Log.i("Scytale","Encrypted data:" + encryptedData);
String decryptedData = crypto.decrypt(encryptedData, key);
Log.i("Scytale","Decrypted data:" + decryptedData);
请注意,无论.jks在主机上的状态如何,仍将需要创建密钥来加密数据。示例中的代码是正确的:
if there is no key in the keystore with that alias
make a new key with that alias
use the key to encrypt and decrypt data.
您在应用程序中要求的密钥库与用于对应用程序进行签名的本地密钥库不是同一密钥库:您可以通过调用ks.containsAlias(alias)进行检查。您必须在运行时密钥库中提供别名。您必须为别名创建一个条目:setEntry(String alias, KeyStore.Entry entry, KeyStore.ProtectionParameter protParam)
(Saves a keystore Entry under the specified alias.)
我不确定您的答案,我需要使用我的密钥库来加密数据,为什么我需要创建一个新别名?
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。