TLS Android的问题 - Netty

时间:2015-06-07 10:40:42

标签: java android ssl netty

我正在使用Android客户端进行客户端 - 服务器应用程序。我需要与服务器进行TLS会话并进行相互身份验证我在服务器上使用Netty。我的客户代码:

// private key
File client_tls_key =  new File("/sdcard/GreatParents/tls/client_key.pkcs8");

KeyManagerFactory kmf = null;
KeyStore ks;
try {
    ks = KeyStore.getInstance("BKS");
    ks.load(new FileInputStream("/sdcard/GreatParents/tls/client_ks.bks"), "changeit".toCharArray());
    String kmf_type = KeyManagerFactory.getDefaultAlgorithm();
    kmf = KeyManagerFactory.getInstance(kmf_type);
    kmf.init(ks, "changeit".toCharArray());
} catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException | UnrecoverableKeyException e) {
    e.printStackTrace();
}
TrustManagerFactory tmf = null;
KeyStore ts;
try {
    ts = KeyStore.getInstance("BKS");
    ts.load(new FileInputStream("/sdcard/GreatParents/tls/client_ts.bks"), "changeit".toCharArray());
    String tmf_type = TrustManagerFactory.getDefaultAlgorithm();
    tmf = TrustManagerFactory.getInstance(tmf_type);
    tmf.init(ts);
} catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) {
    e.printStackTrace();
}
if (tmf != null) {
    SslContext sslCtx = null;
    try {
        sslCtx = SslContext.newClientContext(SslProvider.JDK,null,tmf,null,client_tls_key,keypass,kmf,null,IdentityCipherSuiteFilter.INSTANCE,(ApplicationProtocolConfig) null,0,0);
    } catch (SSLException e) {
        e.printStackTrace();
        logger.error("TLS Session not initialized");
        return;
    }
}

服务器的证书存储在文件client_ts.bks中。客户端的证书存储在文件client_ks.bks中。

我得到了例外:

java.security.NoSuchAlgorithmException: KeyStore JKS implementation not found

我在stacktrace方法中找到了:

io.netty.handler.ssl.JdkSslContext.buildKeyManagerFactory

代码:

KeyStore ks = KeyStore.getInstance("JKS");

Netty创建强制使用JKS-keystores,而不是使用我的BKS-keystore,对吧?!如果我是对的,Netty在TLS部分与Android不兼容。

1 个答案:

答案 0 :(得分:0)

正如您所提到的,“JKS”在Netty中是硬编码的,它们可以使用Keystore.getDefaultType()但不确定是否会引起任何问题。

除此之外,还有一种使用Netty在Android中使用TLS的解决方法。您可以使用JAVA的SSLContext并创建新的SslHandler,以通过SslHandler(SSLContext.createSSLEngine)添加通道管道。

初始化信任管理器工厂后的类似情况:

...

    SSLContext sslContext = SSLContext.getInstance("TLS");
    sslContext.init(kmf.getKeyManagers(),tmf.getTrustManagers(), new SecureRandom());
    SSLEngine sslEngine = sslContext.createSSLEngine();
    sslEngine.setUseClientMode(true);
    SslHandler sslHandler = new SslHandler(sslEngine);
    channel.pipeline().addFirst(sslHandler)

...