当我尝试从Android应用中点击HTTPS URL(.Net Webservice)时,我收到此异常:
javax.net.ssl.SSLException:不受信任的服务器证书
这是我的代码:
HttpParams myParams = new BasicHttpParams();
HttpProtocolParams.setVersion(myParams, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(myParams, "utf-8");
myParams.setBooleanParameter("http.protocol.expect-continue", false);
HttpConnectionParams.setConnectionTimeout(myParams, 100000);
HttpConnectionParams.setSoTimeout(myParams, 100000);
//
KeyStore trusted;
try {
trusted = KeyStore.getInstance("pkcs12");
trusted.load(null, "".toCharArray());
SSLSocketFactory sslf = new SSLSocketFactory(trusted);
sslf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", sslf, 443));
ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(myParams, schemeRegistry);
httpClient = new DefaultHttpClient(manager, myParams);
} catch (KeyStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//
localContext = new BasicHttpContext();
httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109);
httpPost = new HttpPost("https://....");
response = null;
StringEntity tmp = null;
httpPost.setHeader("SOAPAction", "SoapActionURL");
if (contentType != null) {
httpPost.setHeader("Content-Type", contentType);
} else {
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
}
try {
tmp = new StringEntity(data,"UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e("Your App Name Here", "HttpUtils : UnsupportedEncodingException : "+e);
}
httpPost.setEntity(tmp);
try {
response = httpClient.execute(httpPost,localContext);
if (response != null) {
ret = EntityUtils.toString(response.getEntity());
}
} catch (Exception e) {
Log.e("Your App Name Here", "HttpUtils: " + e);
}
答案 0 :(得分:1)
KeyStore trusted;
try {
trusted = KeyStore.getInstance("pkcs12");
trusted.load(null, "".toCharArray());
SSLSocketFactory sslf = new SSLSocketFactory(trusted);
您没有信任库存储您要连接的服务器的证书,并且您要连接的服务器不受信任。要解决此问题,您需要使用Keytool(我创建了一个BKS密钥库并使用SpongyCastle提供程序加载它)作为信任库来创建密钥库文件。
keytool -importcert -file servercert.crt -alias mykey -keystore truststore.jks -storetype BKS -providerpath bcprov-jdk15on-151.jar -provider org.bouncycastle.jce.provider.BouncyCastleProvider
另外,我使用了更新版本的Apache HttpClient,特别是http://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient-android/4.3.5
public KeyStore initializeTrustStore(Context context)
{
KeyStore keyStore = null;
try
{
keyStore = KeyStore.getInstance("BKS", BouncyCastleProvider.PROVIDER_NAME);
InputStream inputStream = context.getResources().openRawResource(R.raw.truststore);
try
{
keyStore.load(inputStream, "password".toCharArray());
}
finally
{
inputStream.close();
}
}
KeyStore trustStore = loadTrustStore(context);
SSLContext sslcontext = null;
CloseableHttpClient httpclient = null;
SSLContextBuilder sslContextBuilder = SSLContexts.custom()
.loadTrustMaterial(trustStore, new TrustSelfSignedStrategy());
sslcontext = sslContextBuilder.build();
// Allow TLSv1 protocol only
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
sslcontext, new String[] {"TLSv1"}, null,
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
);
httpclient = HttpClients
.custom()
.setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)
.setSSLSocketFactory(sslsf).build();
CloseableHttpResponse response = httpclient.execute(httpUriRequest);
try
{
HttpEntity entity = response.getEntity();
//do things with response here
if(entity != null)
{
entity.consumeContent();
}
}
finally
{
response.close();
}