注意:由于其他问题,我最终完全放弃了对Android 2.2的支持......但这个问题仍然是个谜。
我在华为U8150的Android 2.2中遇到过SSL异常。
java.io.IOException: Error parsing the certificates: Ok
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.nativeinit(Native Method)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.init(OpenSSLSocketImpl.java:125)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.<init>(OpenSSLSocketImpl.java:241)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImplWrapper.<init>(OpenSSLSocketImplWrapper.java:35)
at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketFactoryImpl.createSocket(OpenSSLSocketFactoryImpl.java:83)
at org.jivesoftware.smack.tcp.XMPPTCPConnection.proceedTLSReceived(XMPPTCPConnection.java:739)
上面的代码只是设置客户端证书和私钥进行身份验证。该代码在Android 2.3及更高版本上正常运行。
我已经检查了Apache Harmony代码,以了解引擎盖的问题,并且在解析证书链时似乎失败了:http://www.netmite.com/android/mydroid/dalvik/libcore/x-net/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLSocketImpl.java
在功能init()
中:
ByteArrayOutputStream certificateOS = new ByteArrayOutputStream();
PEMWriter certificateWriter = new PEMWriter(new OutputStreamWriter(certificateOS));
for (int i = 0; i < certificates.length; i++) {
certificateWriter.writeObject(certificates[i]);
}
certificateWriter.close();
它只使用PEMWriter
创建PEM格式的连锁链,以将其传递给OpenSSL(通过nativeinit
函数)。
我的应用生成的证书是正版的,使用openssl x509
进行了测试。我不得不说它有一个自定义扩展,但我重申任何比2.2更新的版本都可以工作。
我已在此处上传了证书:http://paste.debian.net/209823/
更新
我一直试图在桌面上重现Android为达到问题点所做的所有步骤,即(标有 CHECK 我已成功尝试过的那些) :
对于第3步,我使用Bouncy Castle 1.49和PEMWriter,就像Android一样。
对于第4步,我创建了一个与OpenSSL 0.9.8m(安装在Android 2.2中的版本)链接的小型C实用程序,它执行相同的函数调用以初始化SSL上下文并从文件加载证书。
现在我剩下的是:
代码发布在此处:https://gist.github.com/daniele-athome/47f458d64aefed6e6c11