Java Android SSLHandshake失败-CA证书
我想保护与套接字的SSL连接。但不幸的是,我的CA证书有问题Java Android SSLHandshake失败-CA证书,java,android,ssl,certificate,handshake,Java,Android,Ssl,Certificate,Handshake,我想保护与套接字的SSL连接。但不幸的是,我的CA证书有问题 javax.net.ssl.SSLHandshakeException: Handshake failed at com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:441) at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:1014) at com.koushikd
javax.net.ssl.SSLHandshakeException: Handshake failed
at com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:441)
at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:1014)
at com.koushikdutta.async.AsyncSSLSocketWrapper$5.onDataAvailable(AsyncSSLSocketWrapper.java:194)
at com.koushikdutta.async.Util.emitAllData(Util.java:23)
at com.koushikdutta.async.AsyncNetworkSocket.onReadable(AsyncNetworkSocket.java:152)
at com.koushikdutta.async.AsyncServer.runLoop(AsyncServer.java:789)
at com.koushikdutta.async.AsyncServer.run(AsyncServer.java:627)
at com.koushikdutta.async.AsyncServer.access$700(AsyncServer.java:41)
at com.koushikdutta.async.AsyncServer$13.run(AsyncServer.java:569)
Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:337)
at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:231)
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:115)
at com.android.org.conscrypt.OpenSSLEngineImpl.verifyCertificateChain(OpenSSLEngineImpl.java:666)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake_bio(Native Method)
at com.android.org.conscrypt.OpenSSLEngineImpl.unwrap(OpenSSLEngineImpl.java:426)
... 8 more
Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
我的代码:
String type = KeyStore.getDefaultType();
KeyStore trustStore = KeyStore.getInstance(type);
trustStore.load(null, null);
trustStore.setCertificateEntry("ca", new CA().getCert());
String tmfAlg = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlg);
tmf.init(trustStore);
try {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
SSLEngine engine = context.createSSLEngine();
AsyncSSLSocketWrapper.handshake(socketNormal, url, port, engine, tmf.getTrustManagers(), new NoopHostnameVerifier(), true, (e, socket1) -> {
// ... more
我的证书在我的资产目录中:
public X509Certificate getCert() throws CertificateException, IOException {
CertificateFactory certFactory;
certFactory = CertificateFactory.getInstance("X.509");
InputStream inputStream = new BufferedInputStream(context.getAssets().open("pem.pem"));
return (X509Certificate) certFactory.generateCertificate(inputStream);
}
我的证书使用私钥签名,并且是自签名的
显然,它在没有确定的情况下工作。。。但这并不安全
编辑:
我已尝试放置现有的BKS密钥库,而不是在运行时动态添加:
KeyStore trustStore = KeyStore.getInstance("BKS");
BufferedInputStream is = new BufferedInputStream(c.getAssets().open("key.bks"));
trustStore.load(is, "12345".toCharArray());
Log.i("Cert", "ca " + (new CA().getCert()).getSubjectDN());
String tmfAlg = TrustManagerFactory.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlg);
tmf.init(trustStore);
try {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
SSLEngine engine = context.createSSLEngine();
AsyncSSLSocketWrapper.handshake(socketNormal, url, port,
engine, tmf.getTrustManagers(), new NoopHostnameVerifier(), true, (e, socket1) -> {
但不幸的是,错误是一样的
编辑2:
更多信息:
- 服务器PHP使用以下方式生成此证书:
function createSSLCert($pem_file, $pem_passphrase, $pem_dn) { // //create ssl cert for this scripts life. //Create private key $privkey = openssl_pkey_new(); //Create and sign CSR $cert = openssl_csr_new($pem_dn, $privkey); $cert = openssl_csr_sign($cert, null, $privkey, 365 * 99);//365 //Generate PEM file $pem = array(); openssl_x509_export($cert, $pem[0]); openssl_pkey_export($privkey, $pem[1], $pem_passphrase); $pem = implode($pem); //Save PEM file //echo $pem; file_put_contents($pem_file, $pem); //chmod($pem_file, 0600); } $pem_passphrase = "XXXXX"; //Set a password here $pem_file = "cert.pem"; //Set a path/filename for the PEM SSL Certificate which will be created. //The following array of data is needed to generate the SSL Cert $pem_dn = array( "countryName" => "PL", //Set your country name "localityName" => "City", //Ser your city name "organizationName" => "Firm name", //Set your company name "commonName" => "CN", //Set your full hostname. "emailAddress" => "admin@email.pl" //Set your email address ); //create ssl cert for this scripts life. $this->createSSLCert($pem_file, $pem_passphrase, $pem_dn);
- 密钥库是使用Portecle工具创建的,如: 新建->BKS->导入受信任证书->我的*pem文件->保存
返回:openssl s_客户端-调试-连接10.100.0.24:5678
Verify return code: 18 (self signed certificate)
加上一些关于证书的私人信息新CA()的功能是什么。getCert()的功能是什么?它是加载现有证书还是生成新证书?@Robert it从资产加载现有证书(我发布了
getCert()
方法的正文)您是否尝试将自签名服务器证书放入BKS密钥库并将其放入资产目录并加载,而不是在运行时动态添加它?Portecle是创建这样一个密钥库的一个简单的UI工具。@Robert是的,我做了-同样的例外我会用标准的HttpsUrlConnection尝试trustmanager,看看AsyncSSLSocketWebRapper是否导致了错误。如果不是,您导入了错误的证书或不是完整的链。新建CA().getCert()做什么?它是加载现有证书还是生成新证书?@Robert it从资产加载现有证书(我发布了getCert()
方法的正文)您是否尝试将自签名服务器证书放入BKS密钥库并将其放入资产目录并加载,而不是在运行时动态添加它?Portecle是创建这样一个密钥库的一个简单的UI工具。@Robert是的,我做了-同样的例外我会用标准的HttpsUrlConnection尝试trustmanager,看看AsyncSSLSocketWebRapper是否导致了错误。如果不是,则导入了错误的证书或不是完整的链。