【问题标题】:Unable to retrieve Private Key from KeyStore无法从 KeyStore 检索私钥
【发布时间】:2017-05-26 16:07:26
【问题描述】:

我正在尝试制作一个使用 RSA 算法进行加密的聊天应用程序。但是,当我尝试解密消息时,我在下面收到此错误。

这是我创建密钥的方式;

  if (!keyStore.containsAlias(alias)) {
                Calendar start = Calendar.getInstance();
                Calendar end = Calendar.getInstance();
                end.add(Calendar.YEAR, 25);
                KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getApplicationContext())
                        .setAlias(alias)
                        .setSubject(new X500Principal("CN=Sample Name, O=Android Authority"))
                        .setSerialNumber(BigInteger.ONE)
                        .setStartDate(start.getTime())
                        .setEndDate(end.getTime())
                        .build();
                KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
                generator.initialize(spec);

            }

这是我尝试解密消息的方法;

定义密钥库;

 static KeyStore keyStore;

在 onCreate 方法中加载 keyStore:

  try{
        keyStore = KeyStore.getInstance("AndroidKeyStore");
        keyStore.load(null);
    } 
    catch (CertificateException | NoSuchAlgorithmException | KeyStoreException | IOException e) {
        e.printStackTrace();
    } 

解密函数:

      public String decryptString(String alias, String decrypted) {
    try {

        KeyStore.Entry entry;
        //ERROR HAPPENS HERE.
        entry = keyStore.getEntry(alias, null);

        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) entry;

        Cipher output = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        output.init(Cipher.DECRYPT_MODE, privateKeyEntry.getPrivateKey());


        CipherInputStream cipherInputStream = new CipherInputStream(
                new ByteArrayInputStream(Base64.decode(decrypted, Base64.DEFAULT)), output);
        ArrayList<Byte> values = new ArrayList<>();
        int nextByte;
        while ((nextByte = cipherInputStream.read()) != -1) {
            values.add((byte) nextByte);
        }

        byte[] bytes = new byte[values.size()];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = values.get(i);
        }

        String finalText = new String(bytes, 0, bytes.length, "UTF-8");
        return finalText;

    } catch (IOException | KeyStoreException | NoSuchPaddingException | UnrecoverableEntryException | InvalidKeyException | NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return "Error";
}

我在下面收到此错误;

E/AndroidRuntime: FATAL EXCEPTION: main
                                                               Process: com.furkan.profil, PID: 10591
                                                               java.lang.NullPointerException: Attempt to invoke virtual method 'java.security.KeyStore$Entry java.security.KeyStore.getEntry(java.lang.String, java.security.KeyStore$ProtectionParameter)' on a null object reference
                                                                   at com.furkan.profil.RSAHelper.decryptString(RSAHelper.java:180)
                                                                   at com.furkan.profil.Chat.ChatActivity$4.onChildAdded(ChatActivity.java:251)
                                                                   at com.google.android.gms.internal.zzblz.zza(Unknown Source)
                                                                   at com.google.android.gms.internal.zzbnz.zzYj(Unknown Source)
                                                                   at com.google.android.gms.internal.zzboc$1.run(Unknown Source)
                                                                   at android.os.Handler.handleCallback(Handler.java:739)
                                                                   at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                   at android.os.Looper.loop(Looper.java:148)
                                                                   at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

【问题讨论】:

  • 好的,所以你已经改变了它。但是,您正在改组在表下创建密钥存储的异常(空的 catch 块,请改用 IllegalStateException),您没有指出发生异常的行,最后您的异常似乎与您的代码不一致。
  • 不,我错了最后一个,你可能需要创建并设置一个(password) call back handler
  • 我添加了 Android Studio 提供给我的一些其他 catch 子句,并在发生异常的地方进行了编辑。我仍然遇到同样的错误。为什么要我使用回调处理程序?能给我解释一下吗?
  • 因为堆栈跟踪中的 android.os.Handler.handleCallback(Handler.java:739) 行。我认为printStackTrace() 不会打印任何内容(我会避免使用printStackTrace,只需使用throw new IllegalStateException("KeyStore could not be initialized", e),因为当您遇到错误时它不会继续运行,并且对于编译器来说,它会被视为退出点) - 并且最后它当然仍然会打印堆栈跟踪。
  • 我改变了所有的 catch 子句并重塑了问题,而不是 throw。但我仍然遇到同样的错误。我已经仔细检查了我的别名,但没关系。

标签: android encryption rsa private-key android-keystore


【解决方案1】:

我刚刚注意到我正在从另一个活动中访问此方法,并且当我尝试访问方法时我没有触发 onCreate() 方法。我补充说;

try{
            keyStore = KeyStore.getInstance("AndroidKeyStore");
            keyStore.load(null);
        } catch (CertificateException | NoSuchAlgorithmException | KeyStoreException | IOException e) {
            throw new IllegalStateException("KeyStore could not be initialized", e);
        }

decryptString() 方法的行。之后我的问题就解决了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多