问题描述
我尝试从 https://gist.github.com/michalbcz/4170520 寻求帮助从具有某些证书问题的站点获取html.我在Eclipse中尝试过,但效果很好,但是在Android中实现时却给了我一些问题. (我是Android新手)我试图通过单击按钮获取文本字段的值,并尝试使用Toast进行显示.
Taking help from https://gist.github.com/michalbcz/4170520 I tried to fetch html from a site which had some certificate issues.I tried in Eclipse and it worked fine, but its giving me some issue when implemented in Android. (I am new to Android)I am trying to fetch the value of a text field on the click of a button and trying to display it using a Toast.
这是代码.
package sample.app;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.provider.SyncStateContract;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.SecureRandom;
import java.util.Date;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class MainActivity extends AppCompatActivity {
public interface Constants {
String LOG = "sample.app";
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ProgressDialog mProgressDialog;
Log.e(Constants.LOG , "we are here");
Button b = (Button)findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new Status().execute();
}
});
}
public class Status extends AsyncTask<Void , Void , Void>{
ProgressDialog mProgressDialog;
public String value = null;
@Override
protected void onPreExecute() {
super.onPreExecute();
EditText userName = (EditText) findViewById(R.id.userName);
EditText passwd = (EditText) findViewById(R.id.editText);
String user = (String)userName.getText().toString();
String pass = (String)passwd.getText().toString();
}
@Override
protected Void doInBackground(Void... params){
SSLContext ctx = null;
try {
ctx = SSLContext.getInstance("TLS");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
try {
ctx.init(new KeyManager[0], new TrustManager[]{new DefaultTrustManager()}, new SecureRandom());
} catch (KeyManagementException e) {
e.printStackTrace();
}
SSLContext.setDefault(ctx);
URL url = null;
HttpsURLConnection conn = null;
try {
url = new URL("https://example.com");
} catch (MalformedURLException e) {
e.printStackTrace();
}
try{
conn = (HttpsURLConnection)url.openConnection();
conn.setHostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String arg0, SSLSession arg1) {
return true;
}
});
}
catch (IOException io){
}
try {
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String input = org.apache.commons.io.IOUtils.toString(br);
Document doc = Jsoup.parse(input);
Date d = new Date();
String loginTime = doc.select("input#loginTime").val();
value = loginTime;
} catch (IOException e) {
e.printStackTrace();
}
conn.disconnect();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
if(value == null){
value = "Nothing";
}
Toast toast = Toast.makeText(MainActivity.this, value, Toast.LENGTH_LONG);
toast.show();
}
}
private static class DefaultTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
}
我检查了日志,这是我收到错误消息的地方:
I checked the logs and this is the place where I am getting an error:
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
br
正在获取null
值,因此存在异常,并且我无法获取想要的值.任何帮助,将不胜感激.谢谢.
The br
is getting a null
value hence there is an exception and I am not able to fetch the value I intend to.Any help on this will be appreciated. Thanks.
这是我得到的例外.
01-04 09:01:16.800 9483-14095/? E/ERR: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:328)
at com.android.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:103)
at com.android.okhttp.Connection.connect(Connection.java:143)
at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185)
at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:437)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:388)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:231)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java)
at sample.app.MainActivity$Status.doInBackground(MainActivity.java:138)
at sample.app.MainActivity$Status.doInBackground(MainActivity.java:68)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
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:318)
at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:219)
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:115)
at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:556)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:324)
at com.android.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:103)
at com.android.okhttp.Connection.connect(Connection.java:143)
at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185)
at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:437)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:388)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:231)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java)
at sample.app.MainActivity$Status.doInBackground(MainActivity.java:138)
at sample.app.MainActivity$Status.doInBackground(MainActivity.java:68)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:318)
at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:219)
at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:115)
at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:556)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:324)
at com.android.okhttp.internal.http.SocketConnector.connectTls(SocketConnector.java:103)
at com.android.okhttp.Connection.connect(Connection.java:143)
at com.android.okhttp.Connection.connectAndSetOwner(Connection.java:185)
at com.android.okhttp.OkHttpClient$1.connectAndSetOwner(OkHttpClient.java:128)
at com.android.okhttp.internal.http.HttpEngine.nextConnection(HttpEngine.java:341)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:330)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:248)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:437)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:388)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:231)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.getInputStream(DelegatingHttpsURLConnection.java:210)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java)
at sample.app.MainActivity$Status.doInBackground(MainActivity.java:138)
at sample.app.MainActivity$Status.doInBackground(MainActivity.java:68)
at android.os.AsyncTask$2.call(AsyncTask.java:295)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
at java.lang.Thread.run(Thread.java:818)
推荐答案
尝试解决问题的一些选项:
Some options to try for solving your issue:
基本上,替换此行:
ctx = SSLContext.getInstance("TLS");
使用
ctx = SSLContext.getInstance("SSL");
2)使用可以接受任何https连接的TrustManager
@Override
protected Void doInBackground(Void... params){
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
}
} };
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
throw new RuntimeException(e);
}
// Your code ...
URL url = null;
HttpsURLConnection conn = null;
try {
url = new URL("https://example.com");
} catch (MalformedURLException e) {
e.printStackTrace();
}
// ...
}
这篇关于Android Jsoup证书问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!