2017-05-17 29 views
0

我试图使用this gist加密我的应用程序中的一些数据。KeyStore没有找到我的别名密钥

我已经用我的别名“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相同的别名吗?

谢谢!

+0

你尝试过在命令行列出密钥库别名HTTP://stackoverflow.com/a/12894334/1056359 – thepoosh

+0

是,别名它的确定,我试着它调试与已签名的apk –

+0

哪行代码发生异常?确保您正在使用正在运行应用程序的jre中的正确密钥库。使用的运行时JRE可以是不同的,包含不带别名的不同密钥库。 – Sonic

回答

2

答案从Sonic是在您用来签署应用程序是你在你的应用程序中使用的密钥库不同Java Key Store正确。前者是开发机器(您的笔记本电脑)上的文件,而后者仅在您安装应用程序的手机上(Android手机或模拟器)。对您的apk签名,以便它可以在Play商店上发布,并在您的数据上加密用户的私人数据是不同的程序。

在不明确的情况下,您应该尝试引用典范来源而不是任意要求和教程,这些要素在质量上差别很大。在这种情况下,official Android documentation for KeyStore有一个存储密钥的完整示例。请注意,Gist中引用的Android KeyStore仅适用于API 18+。

无可否认,官方文档和Gist中的代码示例相当复杂,很容易出错。更好的选择可能是Scytale之类的东西。这是围绕正确处理的情况下密钥库的包装,其中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. 
1

您在应用程序中要求的密钥库与您本地密钥库签署应用程序的密钥库不同:您可以通过调用ks.containsAlias(alias)来检查该密钥库。您必须在运行时密钥库中提供别名。你必须为你的别名项:setEntry(String alias, KeyStore.Entry entry, KeyStore.ProtectionParameter protParam) (Saves a keystore Entry under the specified alias.)

+0

林不知道你的答案,我需要使用我的密钥库来加密数据,为什么我需要创建一个新的别名? –

相关问题