我正在使用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不兼容。
答案 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)
...