我在寻找忽略默认httpclient中所有ssl错误(如不可信)的可能性。我在这里看到了很多解决方案,但是我总是需要导入一个特定的证书并将其添加到信任管理器中,或者是用于defaulthttpclient的httpsurlconnection instad。
我使用的web请求是:
public static String makeGETRequest(String s,String encoding)
{
DefaultHttpClient http = new DefaultHttpClient();
final String username = "USERNAME";
final String password = "PASSWORD";
UsernamePasswordCredentials c = new UsernamePasswordCredentials(username,password);
BasicCredentialsProvider cP = new BasicCredentialsProvider();
cP.setCredentials(AuthScope.ANY, c);
http.setCredentialsProvider(cP);
HttpResponse res;
try {
res = http.execute(new HttpGet(s));
InputStream is = res.getEntity().getContent();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while((current = bis.read()) != -1){
baf.append((byte)current);
}
return new String(baf.toByteArray(),encoding);
}
catch (ClientProtocolException e) {
// TODO Auto-generated catch block
return "error: " + e.getMessage();
}
catch (IOException e) {
// TODO Auto-generated catch block
return "error: " + e.getMessage();
}
}
还有:
public static String makePOSTRequest(String s, List <NameValuePair> nvps,String encoding)
{
DefaultHttpClient http = new DefaultHttpClient();
final String username = "USERNAME";
final String password = "PASSWORD";
UsernamePasswordCredentials c = new UsernamePasswordCredentials(username,password);
BasicCredentialsProvider cP = new BasicCredentialsProvider();
cP.setCredentials(AuthScope.ANY, c);
http.setCredentialsProvider(cP);
HttpResponse res;
try {
HttpPost httpost = new HttpPost(s);
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.DEFAULT_CONTENT_CHARSET));
res = http.execute(httpost);
InputStream is = res.getEntity().getContent();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while((current = bis.read()) != -1){
baf.append((byte)current);
}
res = null;
httpost = null;
String ret = new String(baf.toByteArray(),encoding);
return ret;
}
catch (ClientProtocolException e) {
// TODO Auto-generated catch block
return e.getMessage();
}
catch (IOException e) {
// TODO Auto-generated catch block
return e.getMessage();
}
}
有人知道如何忽略这段代码中的ssl错误吗?
编辑:
因为我只需要信任一个特定(过期)证书,所以我尝试以下方式覆盖DefaultHttpClient:
public class MyHttpClient extends DefaultHttpClient {
final Context context;
public MyHttpClient(Context context) {
this.context = context;
}
@Override protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
registry.register(
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", newSslSocketFactory(), 443));
return new SingleClientConnManager(getParams(), registry);
}
private SSLSocketFactory newSslSocketFactory() {
try {
KeyStore trusted = KeyStore.getInstance("BKS");
InputStream in = context.getResources().openRawResource(R.raw.mykeystore);
try {
trusted.load(in, "mypassword".toCharArray());
} finally {
in.close();
}
return new SSLSocketFactory(trusted);
} catch (Exception e) {
throw new AssertionError(e);
}
}
}
在r.raw.mykeystore中的文件是一个.bks文件,我使用Portecle创建了一个新的bks,并导入了存储的过期证书的pem,它看起来可以正常工作,并且keystored加载时没有错误,但是如果我执行请求,就会收到一个io异常,消息是“no peer certificate”,有什么问题吗?
最佳答案
我解决了这个问题。如果您使用上述请求,但不使用DefaultHttpClient,而是使用您自己的版本,则可以正常工作:
public class MyHttpClient extends DefaultHttpClient {
final Context context;
TrustManager easyTrustManager = new X509TrustManager() {
@Override
public void checkClientTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(
X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
public MyHttpClient(Context context) {
this.context = context;
}
@Override protected ClientConnectionManager createClientConnectionManager() {
SchemeRegistry registry = new SchemeRegistry();
registry.register(
new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", newSslSocketFactory(), 443));
return new SingleClientConnManager(getParams(), registry);
}
private MySSLSocketFactory newSslSocketFactory() {
try {
KeyStore trusted = KeyStore.getInstance("BKS");
try {
trusted.load(null, null);
} finally {
}
MySSLSocketFactory sslfactory = new MySSLSocketFactory(trusted);
sslfactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
return sslfactory;
} catch (Exception e) {
throw new AssertionError(e);
}
}
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();
}
}
}
关于android - 忽略DefaultHttpClient中的ssl错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7229929/