Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
接收及;验证来自HTTPS服务器的证书-android_Android_Web Services_Ssl_Certificate - Fatal编程技术网

接收及;验证来自HTTPS服务器的证书-android

接收及;验证来自HTTPS服务器的证书-android,android,web-services,ssl,certificate,Android,Web Services,Ssl,Certificate,我正在通过https从我的android客户端调用web服务。我必须验证从服务器端接收的证书。我该怎么做?目前,这是我用来调用web服务的代码 private static String SendPost(String url, ArrayList<NameValuePair> pairs) { // url = "https://....." errorMessage = ""; String response = ""; Defau

我正在通过https从我的android客户端调用web服务。我必须验证从服务器端接收的证书。我该怎么做?目前,这是我用来调用web服务的代码

private static String SendPost(String url, ArrayList<NameValuePair> pairs) {   // url = "https://....."   
    errorMessage = "";   
    String response = "";   

    DefaultHttpClient hc=new DefaultHttpClient();      
    ResponseHandler <String> res=new BasicResponseHandler();      
    HttpPost postMethod=new HttpPost(url);   

    try {   
postMethod.setEntity(new UrlEncodedFormEntity(pairs));   
        response = hc.execute(postMethod, res);   
    } catch (UnsupportedEncodingException e) {   
        e.printStackTrace();   
    } catch (ClientProtocolException e) {   
        e.printStackTrace();   
    } catch (IOException e) {   
        e.printStackTrace();   
    }        

    return response;   
}  
私有静态字符串SendPost(字符串url,数组列表对){//url=”https://....."   
errorMessage=“”;
字符串响应=”;
DefaultHttpClient hc=新的DefaultHttpClient();
ResponseHandler res=新的BasicResponseHandler();
HttpPost postMethod=新的HttpPost(url);
试试{
setEntity(新的UrlEncodedFormEntity(对));
响应=hc.execute(后方法,res);
}捕获(不支持的编码异常e){
e、 printStackTrace();
}catch(ClientProtocolException e){
e、 printStackTrace();
}捕获(IOE){
e、 printStackTrace();
}        
返回响应;
}  
如何在执行Post期间验证从服务器接收的自签名证书?我必须通过公钥/私钥进行测试。客户端将有一个CA文件。我只需要客户端使用CA验证服务器证书,服务是公共的。这与公钥/私钥有关。在调用post之前,我如何从服务器接收证书

stackoverflow上提供了几个选项和代码段。我找到的多个答案的几个链接是:

但我看不出哪一个适合我!我不想禁用所有或接受任何。必须检查公钥/私钥/


非常感谢您的帮助

Bob Lee写了一篇很好的博客文章,介绍了如何在Android上使用SSL证书。我认为它适用于你的情况:

您只需创建一个包含自签名证书的
KeyStore
,并使用该帖子中描述的自定义
HttpClient
实现


更新:

可以在
SSLSocketFactory
上自定义主机名验证。android中已有一些实现:
AllowlHostNameVerifier
BrowserCompatHostnameVerifier
StricHostNameVerifier

/* ... */
public class MyHostnameVerifier extends AbstractVerifier {
  boolean verify(String hostname, SSLSession session) {
    X509Certificate[] chain = session.getPeerCertificateChain();
    /* made some checks... */
    return checked;
  }
}
sslSocketFactory.setHostnameVerifier(new MyHostnameVerifier());

如何从服务器接收证书和测试数据?您无需执行任何操作。证书在SSL握手期间由服务器发送,并由客户端应用程序根据密钥库内容自动验证。握手是在交换任何HTTP数据之前执行的。如果您想执行更复杂的或自定义的证书验证,这也是可能的(但在这篇评论中解释起来有点长)@Jcs,我已经有了必须使用的certificate.cer文件。我不明白那个有弹性城堡的部分。另外,我没有任何密码可以传递给trusted.load()????SSLSocketFactory构造函数需要一个KeyStore,这就是为什么不能直接传递certificate.cer文件,而必须将其包装到KeyStore对象中。Android不支持旧的java密钥库格式(又名JKS),但它支持BouncyCastle设计的密钥库格式(又名BKS)。通过将BouncyCastle库添加到类路径中,keytool能够创建具有BKS格式的密钥库。创建密钥库时,密码是可选的;您可以忽略此选项并将null传递给load()方法。感谢Jcs的解释。我成功地创建了bks文件,并从服务器接受vert并访问web服务。但有两个问题:1)默认域是“aa-e3.mysite.com”。我有一个域名列表,列出任何域名,并连接到该域名,它可能是“we-e3.mysite.com”或其他什么。只有当prg选择的域是默认域时,我才能访问WS,对于其他所有我得到的SSLExcep“certi中的主机名不匹配:!=”。如何处理?