我有以下用 Java 编写的源代码,它创建到远程服务器的 https 连接并向 http 服务器发出一些请求:
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.util.*;
import java.security.cert.X509Certificate;
import java.security.*;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpEntity;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
public class trustStore {
public static void main(String[] args) throws Exception {
char[] password = "OQASNRati6c=".toCharArray();
FileInputStream fIn = new FileInputStream("lamkin.p12");
KeyStore keystore = KeyStore.getInstance("PKCS12");
keystore.load(fIn, password);
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore, new TrustSelfSignedStrategy()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
try {
HttpGet httpget = new HttpGet("https://172.20.175.1/kani/");
System.out.println("executeng request" + httpget.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httpget);
try {
HttpEntity entity = response.getEntity();
System.out.println("-------------------------------");
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content lingth: " + entity.getContentLength());
}
EntityUtils.consume(entity);
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
}
我尝试对 android 平台做同样的事情,但我遇到了问题:如何在 android 应用程序中发布下一个代码字符串:
SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore, new TrustSelfSignedStrategy()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1" }, null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
我在 Android SDK CloseableHttpClient、SSLContexts、SSLConnectionSOcketFactory 中没有找到。谁能告诉我什么是 SSLSocketFactory?为什么需要它?
更新:
我尝试以下代码行:
FileInputStream fIn = new FileInputStream("lamkin.p12");
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(fIn, password);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, password);
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
URL url = new URL("https://kompot.petrsu.ru/kani/");
HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStream in = urlConnection.getInputStream();
它不适用于 Ubuntu 操作系统,出现以下异常:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
我在 Android 操作系统上做了同样的事情,然后我得到了以下异常:
04-11 11:35:30.123: W/System.err(4880): javax.net.ssl.SSLHandshakeException:
java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
04-11 11:35:30.133: W/System.err(4880): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:401)
04-11 11:35:30.133: W/System.err(4880): at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
04-11 11:35:30.133: W/System.err(4880): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
04-11 11:35:30.133: W/System.err(4880): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
etc...
可能有什么问题?