在Android中隐藏密钥库密码的最佳方法是什么?


问题内容

我是Android开发和实现SSLSockets的新手。经过一些挖掘后,我能够设置一个可以正常工作的简单服务器/客户端。我觉得该实现可能需要花费一些工作,并且在不使用纯文本格式的情况下困扰于如何将密码加载到密钥库中。这是客户端上的一些代码。如您所见,我已将密码硬编码到本地变量中。有没有更好的方法来加载密钥库密码,所以我在代码中没有纯文本格式?

    char [] KSPASS = "password".toCharArray();
    char [] KEYPASS = "password".toCharArray();
    try {
        final KeyStore keyStore = KeyStore.getInstance("BKS");
        keyStore.load(context.getResources().openRawResource(R.raw.serverkeys), KSPASS);

        final KeyManagerFactory keyManager = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManager.init(keyStore, KEYPASS);

        final TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustFactory.init(keyStore);

        sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyManager.getKeyManagers(), trustFactory.getTrustManagers(), null);
        Arrays.fill(KSPASS, ' ');
        Arrays.fill(KEYPASS, ' ');

        KSPASS = null;
        KEYPASS = null;

更新:

事实证明,客户端根本不需要知道密钥库密码。我修改了代码以将null作为密码传递。到目前为止,初始测试已经可以与服务器通信。在服务器端,我仍然加载密钥库密码。

        final KeyStore keyStore = KeyStore.getInstance("BKS");
        keyStore.load(context.getResources().openRawResource(R.raw.serverkeys), null);

        final KeyManagerFactory keyManager = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        keyManager.init(keyStore, null);

        final TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        trustFactory.init(keyStore);

        sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyManager.getKeyManagers(), trustFactory.getTrustManagers(), null);

问题答案:

好吧,这不是一个容易解决的问题。

例如,您可以在应用程序启动时向用户请求密码,以便密码不会硬编码在您的代码中。我认为这是最安全的方法。

如果这不可能,那么如果有人可以访问罐子并“看到”代码和随后的密码,就会出现问题。您可以委托保护这些罐子的用户。

如果无法做到这一点,则可以加密密码并将其存储在某处。然后在您的代码中对密钥进行硬编码以解密密码。因此,看着罐子的人看不到您的真实密码,只有解密密钥。当然,如果真心付出,他可以获取密钥并尝试找到密码所在的位置,然后解密并获取密钥,但这需要更多的努力。

最后,这取决于您的安全要求