2015-06-07 4 views
0

Я работаю над Android-клиентом для клиент-серверного приложения. Мне нужен сеанс TLS с сервером с взаимной аутентификацией. Я использую Netty на сервере. Код моего клиента:Проблемы с TLS Android - 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"); 

Нетти создает JKS-хранилище ключей вынужден, вместо того, чтобы использовать свои BKS -экисторы, верно ?! Если я прав, Netty не совместим с Android в части TLS.

ответ

0

Как вы упомянули, «JKS» жестко закодирован в Netty, они могут использовать Keystore.getDefaultType(), но не уверены, могут ли это вызвать какие-либо проблемы или нет.

Кроме того, есть обходной путь для использования TLS в Android с использованием Netty. Вы можете использовать SSLContext JAVA и создать новый 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) 

...