我希望你们可以帮助我解决这个问题,我做了所有研究并尝试了我所看到的任何东西,但它无法解决我的问题。我想要做的是相信我的应用程序中的所有SSL证书。我看到的所有解决方案都使用URLHttpConnection,但我需要AndroidHttpClient的工作解决方案。请参阅下面的代码:
AndroidHttpClient httpClient = null;
HttpResponse httpResponse;
Bundle responseBundle;
try{
httpClient = AndroidHttpClient.newInstance("android");
httpClient = addCustomCertificate(httpClient);
httpResponse = httpClient.execute(request);
responseCode = httpResponse.getStatusLine().getStatusCode();
message = httpResponse.getStatusLine().getReasonPhrase();
HttpEntity entity = httpResponse.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
String response = convertStreamToString(instream);
responseBundle = new Bundle();
responseBundle.putString("result", response);
responseBundle.putInt("responseCode", responseCode);
receiver.send(method, responseBundle);
instream.close();
httpClient.close();
}
}
// ====
private AndroidHttpClient addCustomCertificate(AndroidHttpClient client)
{
SSLSocketFactory sf = SSLSocketFactory.getSocketFactory();
try
{
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
sf = new SSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
}
catch (Exception t)
{
t.printStackTrace();
}
client.getConnectionManager().getSchemeRegistry().register(new Scheme("https", sf, 443));
return client;
}
但我总是在我在日志中捕获的图像中显示错误。我无法弄清楚我可以做什么其他解决方案。
答案 0 :(得分:1)
请检查下面的1,2,3方法我使用它获取SSSl证书getNewHttpClient
并且对我来说工作正常。我们会帮助你。
1.Api调用函数,需要使用Asynck Task
doInBackground()
public String PostConnection(String strUrl,ArrayList<NameValuePair> alstNameValuePair ) {
Log.d("Stadshart Woerden ","Request URL : "+strUrl);
Log.d("Stadshart Woerden ","Request Parameters : "+alstNameValuePair.toString());
InputStream mInputStream = null;
try {
HttpClient mHttpClient = getNewHttpClient();
HttpPost mHttpPost = new HttpPost(strUrl);
if(alstNameValuePair!=null)
{
//post the value you want to pass.
mHttpPost.setEntity(new UrlEncodedFormEntity(alstNameValuePair));
}
//get the value from the server side as response.
HttpResponse mHttpResponse = mHttpClient.execute(mHttpPost);
HttpEntity mHttpEntity = mHttpResponse.getEntity();
mInputStream = mHttpEntity.getContent();
}
catch (Exception e) {
e.printStackTrace();
}
String strLine = null;
String strResult = null;
//convert response in to the string.
try {
if(mInputStream!=null){
BufferedReader mBufferedReader = new BufferedReader(new InputStreamReader(mInputStream,HTTP.UTF_8), 8);
StringBuilder mStringBuilder = new StringBuilder();
while((strLine = mBufferedReader.readLine()) != null) {
mStringBuilder.append(strLine + "\n");
}
strResult = mStringBuilder.toString();
mInputStream.close();
}
}
catch (Exception e) {
e.printStackTrace();
}
Log.d("Stadshart Woerden ","Response : "+strResult);
return strResult;
}
2
private HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
3
public class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] { tm }, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
答案 1 :(得分:0)
我会告诉你我的解决方案。但这并不是你提出的要求。我将向您展示如何信任一台服务器(意味着您已经知道要调用哪个服务器,因此您可以下载其证书)。
public static String getConnResponse(String url, String input,
boolean isGet, boolean isJson) throws IOException {
if (Constants.SocketFactory == null) {
CertificateFactory cf;
try {
cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new URL("URL_OF_CERTIFICATE").openStream();
Certificate ca = cf.generateCertificate(caInput);
String keyStoreType = KeyStore.getDefaultType();
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory
.getDefaultAlgorithm();
TrustManagerFactory tmf = TrustManagerFactory
.getInstance(tmfAlgorithm);
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
Constants.SocketFactory = context.getSocketFactory();
} catch (CertificateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyStoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
HttpURLConnection conn;
if (isGet) {
if (input == null) {
conn = (HttpURLConnection) new URL(url).openConnection();
} else {
conn = (HttpURLConnection) new URL(url + "?" + input)
.openConnection();
}
if (Constants.SocketFactory!=null){
((HttpsURLConnection) conn).setSSLSocketFactory(Constants.SocketFactory);
}
conn.setRequestProperty("Accept", "application/json,text/html");
conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Cookie", input);
} else {
conn = (HttpURLConnection) new URL(url).openConnection();
if (Constants.SocketFactory!=null){
((HttpsURLConnection) conn).setSSLSocketFactory(Constants.SocketFactory);
}
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", isJson ? "application/json"
: "application/x-www-form-urlencoded");
OutputStream os = conn.getOutputStream();
if(input!=null){
os.write(input.getBytes("UTF-8"));
}
os.flush();
os.close();
}
try {
InputStream is = conn.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is,
"UTF-8"));
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
br.close();
is.close();
conn.disconnect();
return sb.toString();
} catch (SocketException e) {// connection reset
return null;
} catch (Exception e) {// connection reset
return null;
}
}
Constants.SocketFactory 是我用来存储套接字工厂的静态变量,所以以后我不需要再次下载它。 URL_OF_CERTIFICATE 是您的证书的网址,您可以将其上传到您的云端,您也可以将证书放入资产文件夹,这样您就不需要下载它了。但是这个解决方案的缺点是下次你想要与不同的服务器交谈,你需要建立一个新的应用程序。我知道这不是你要求的,但我仍然决定在这里发布,希望它会给你一些线索,或者可能对其他人有类似的问题。