【发布时间】:2011-08-29 12:14:08
【问题描述】:
我正在寻找忽略默认 httpclient 中所有 ssl 错误(例如,不受信任)的可能性。我在这里看到了很多解决方案,但我总是必须导入一个特定的证书并将其添加到信任管理器,或者它是用于 DefaultHttpClient 的 HttpsUrlConnection 的。 我使用的网络请求是:
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 异常,可能是什么问题?
【问题讨论】:
-
“忽略 SSL 错误(例如不受信任)”是不安全的。请参阅 RFC 2246。如果您不希望它安全,为什么要使用 SSL?
-
感谢您转换为评论;)正如我所写,过期的 ssl 证书来自第三方代理,我告诉他们安装一个有效的,但我必须编写一个快速的解决方法来启用为我的客户提供功能,而证书已过期...
-
根据 EJP 的评论,选择性地容忍过期的证书并让任何证书通过是非常不同的事情。