我使用apache mina在我的服务器和Android客户端之间进行通信。当我通过不安全的连接进行连接时,一切都很好,但几天前我决定用ssl保护连接。 Apache mina有一个名为SslFilter的过滤器,用于完成任务 - 它使用ssl上下文,我们提供密钥库和信任库来建立安全连接。一切都像魅力一样,如果我在为客户端写的PC上使用sslfilter和mina,但是当我试图在android上使用它时 - 这并不是那么简单。首先,我们必须导入从服务器SUN格式化密钥库中提取的证书,并将其转换为匹配bouncy castle provider - 因为它似乎是android上唯一的安全提供程序。好的,我可以使用keytool和正确的命令轻松实现这一点。然后我将信任库加载到android中的上下文,就像在PC上一样,并在连接到服务器之后(注意,android客户端安全提供程序是BouncyCastle,而服务器安全提供程序是SUN)我在服务器上获取了这样的日志:
86992 [NioProcessor-3] DEBUG AuthenticationManager - 会话已关闭:2 260628 [NioProcessor-1] DEBUG SslFilter - 将SSL过滤器sslFilter添加到链中 260629 [NioProcessor-1] DEBUG SslHandler - 会话服务器[3](无sslEngine)初始化SSL Han dler 260642 [NioProcessor-1] DEBUG SslHandler - 会话服务器[3](无sslEngine)SSL处理程序初始化 完成。 260644 [NioProcessor-1] DEBUG SslFilter - 会话服务器3:开始第一次握手 260646 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理NEED_UNWRAP sta TE 260703 [NioProcessor-1] DEBUG SslFilter - 会话服务器3:收到消息:HeapBuffer [ pos = 0 lim = 78 cap = 2048:16 03 01 00 49 01 00 00 45 03 01 C4 C4 C4 C4 80 ...] 260704 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理收到的消息 Ë 260709 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理NEED_UNWRAP sta TE 260709 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理NEED_TASK状态
260710 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理NEED_WRAP状态
260711 [NioProcessor-1] DEBUG SslFilter - 会话服务器3:写入消息:WriteRequest :HeapBuffer [pos = 0 lim = 678 cap = 1057:16 03 01 02 A1 02 00 00 46 03 01 50 5C 17 25 F6 ...] 260711 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理NEED_UNWRAP sta TE 260712 [NioProcessor-1] DEBUG SslFilter - 会话服务器3:处理SSL数据 260867 [NioProcessor-1] DEBUG SslFilter - 会话服务器3:收到消息:HeapBuffer [ pos = 0 lim = 139 cap = 2048:16 03 01 00 86 10 00 00 82 00 80 10 B7 5D AC B3 ...] 260868 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理收到的消息 Ë 260868 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理NEED_UNWRAP sta TE 260869 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理NEED_TASK状态
260876 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理NEED_UNWRAP sta TE 260877 [NioProcessor-1] DEBUG SslFilter - 会话服务器3:处理SSL数据 261133 [NioProcessor-1] DEBUG SslFilter - 会话服务器3:收到消息:HeapBuffer [ pos = 0 lim = 43 cap = 1024:14 03 01 00 01 01 16 03 01 00 20 65 07 FB 0F 1B ...] 261134 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理收到的消息 Ë 261135 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理NEED_UNWRAP sta TE 261154 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理NEED_WRAP状态
261157 [NioProcessor-1] DEBUG SslFilter - Session Server3:编写消息:WriteRequest :HeapBuffer [pos = 0 lim = 6 cap = 8:14 03 01 00 01 01] 261158 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理NEED_WRAP状态
261159 [NioProcessor-1] DEBUG SslFilter - Session Server3:编写消息:WriteRequest :HeapBuffer [pos = 0 lim = 37 cap = 66:16 03 01 00 20 83 D9 81 59 21 9E 03 32 A3 49 17 ...] 261159 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理FINISHED状态 261160 [NioProcessor-1] DEBUG SslHandler - 会话服务器3现已受到保护 261160 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理FINISHED状态 261161 [NioProcessor-1] DEBUG SslHandler - 会话服务器3现已受到保护 261161 [NioProcessor-1] DEBUG SslFilter - 会话服务器3:处理SSL数据
正如你所看到的 - 一切都很好。
261160 [NioProcessor-1] DEBUG SslHandler - 会话服务器3现已受到保护 261160 [NioProcessor-1] DEBUG SslHandler - 会话服务器3处理FINISHED状态 261161 [NioProcessor-1] DEBUG SslHandler - 会话服务器3现已受到保护
上面的清单显示现在已确保连接安全。成功!! HURAY !!但完全没有,因为成功的SSL' dance' android客户端试图以与pc客户端相同的方式发送消息......然后没有任何反应。什么都没有..应用程序挂起在SslFiter编码方法的调用omewhere ..服务器不接收任何消息。我听说android上的ssl存在一些问题 - 您认为可能就是这种情况吗?
一个重要的注意事项。我也试过更改Server上的提供程序,我已经将BouncyCastle安全提供程序导入java扩展提供程序以匹配android上使用的提供程序,然后我已经在java.security中注册了它,结果是一样的即使是仍然使用SUN提供商的PC客户端也可以通过BouncyCastle提供商与服务器成功通信 - 所以我确保自己并非如此。
以上,注意无效。我确信我在服务器上将提供程序更改为BC,但我认为这不是事实。事实上,apache mina隐藏了一些关于SSLContext创建的细节,并且上下文是使用默认提供程序创建的,这是sun提供程序(我现在有点困惑,然后SUN提供程序如何正确加载BKS格式的存储)。 **实际上我无法在我的电脑上创建使用TSL和BouncyCastle提供程序的SSLContext
SSLContext cdt = SSLContext.getInstance("TLS", new BouncyCastleProvider());
或
SSLContext cdt = SSLContext.getInstance("TLS", "BC");
我得到了以下异常" java.security.NoSuchAlgorithmException:没有这样的算法:提供商BC的TLS " - 似乎因为BC是JCE提供者而SSLContext属于JSSE。所以我没有证明自己的假设是我在android" bc provider" - 服务器" sun提供商"通信是因为在交换数据时加密期间某些提供商特定的算法差异。**
如果有人遇到与mina,android和ssl类似的问题,我会感谢任何建议...
答案 0 :(得分:0)
尝试静态设置提供程序:
import org.bouncycastle.jce.provider.BouncyCastleProvider;
static {
Security.addProvider(new BouncyCastleProvider());
}