如果我在Android中使用SSLSocket并且硬编码源代码中的信任库的密码是不安全的?

min*_*az1 4 java encryption ssl android

我正在使用java的SSLSocket将android应用程序安全地连接到服务器.证书位于信任库中.但是信任库的密码似乎是连接所必需的,因此它当前被硬编码到设备中.我对PKI知之甚少,但这似乎并不安全.我将信任库与原始资源文件夹中的应用程序捆绑在一起.有没有更好的方法来安全地允许应用程序使用TLS连接到服务器?我对TLS/SSL非常新,所以我将不胜感激任何帮助或建议.

这是代码的客户端.

        store = KeyStore.getInstance("BKS"); 
        InputStream in = appcontext.getResources().openRawResource(R.raw.truststore);
        store.load(in, "PASSWORD".toCharArray());

        TrustManagerFactory tmf = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        tmf.init(store);
        sslcontext = SSLContext.getInstance("TLS");
        sslcontext.init(null, tmf.getTrustManagers(), new SecureRandom());

        SSLSocketFactory sslsocketfactory = sslcontext.getSocketFactory();

        // connect to socket
        SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(
                "192.168.1.16", 9999);
Run Code Online (Sandbox Code Playgroud)

Bru*_*uno 5

我没有试过Android,但这是它在普通Java中的工作原理.

您在此处使用密钥库作为信任库,因此(希望)它不包含任何私钥或秘密材料.在这种情况下,密码的目的是验证商店的完整性.

Keystore.load(InputStream, char[])文档:

可以给出密码以解锁密钥库(例如,密钥库驻留在硬件令牌设备上),或者检查密钥库数据的完整性.如果没有给出完整性检查的密码,则不执行完整性检查.

您可以使用null密码(在这种情况下,您始终可以加载证书),或者使用char带有实际密码的非空数组(在这种情况下,错误的密码将失败,例如" java.io". IOException:Keystore被篡改,或密码不正确 ").

在这里使用密码意味着增加安全性(以防止信任库被篡改).话虽这么说,如果你将这个信任库和这个应用程序捆绑在一起,那么无论如何,能够替换信任库的攻击者也可能获得密码访问权限(通过反编译).(我不太熟悉Android应用程序分发,但如果应用程序已签名,则篡改您的信任库等原始资源也可能使签名无效,因此这可能是一种更现实的方法来获得此保护.否则,我想你可以要求用户每次都输入信任库的密码,但这似乎不切实际.)


这不是您的问题的一部分,但为了保护SSL/TLS连接,您还需要验证服务器发送的证书是否对您尝试访问的主机名有效SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("192.168.1.16", 9999);.

最近在Java 中的这个问题对此进行了讨论.(不幸的是,您将无法使用新的Java 7 API在Android上自动执行此操作,因此您必须手动检查证书.您可能也对此最近的问题感兴趣.)


编辑(跟随你的评论):

我担心有人重新编译应用程序,检索密码和信任库并使用它连接到我的服务器.如果有可能那么它首先会破坏TLS的目的.

从这个评论中你不清楚你理解信任库的目的(例如,参见这个问题).

客户端应用程序中信任库的目的不是要向服务器验证您的应用程序,而是确保您的客户端可以验证它连接到的服务器的身份,以便它不会被欺骗连接到服务器MITM攻击者.这不是关于您的服务器如何信任您的应用程序/客户端/用户,而是关于您的应用程序如何信任您的服务器.

将app用户验证到服务器将是密钥库的目的.这对于验证用户来说很好(但是如果每个用户都有不同的证书,那就更有意义了).确保连接只能来自您的应用程序是另一个更困难的问题(如果您无法始终完全控制客户端硬件,则会导致丢失原因).在您的应用程序中使用通用客户端证书可能会给您带来一些时间,但任何掌握了客户端代码的人最终都可以对其进行逆向工程.我不会花太多时间在上面.您可能对以下问题感兴趣: