android https安全连接

时间:2022-04-26
本文章向大家介绍android https安全连接,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

如果不需要验证服务器端证书,直接照这里做

 public class Demo extends Activity {  
  /** Called when the activity is first created. */ 
  private TextView text;  
  @Override 
  public void onCreate(Bundle savedInstanceState) {  
  super.onCreate(savedInstanceState);  
         setContentView(R.layout.main);  
         text = (TextView)findViewById(R.id.text);  
         GetHttps();  
     }  
  
  private void GetHttps(){  
             String https = " https://800wen.com/";  
  try{  
                     SSLContext sc = SSLContext.getInstance("TLS");  
                     sc.init(null, new TrustManager[]{new MyTrustManager()}, new SecureRandom());  
                     HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());  
                     HttpsURLConnection.setDefaultHostnameVerifier(new MyHostnameVerifier());  
                     HttpsURLConnection conn = (HttpsURLConnection)new URL(https).openConnection();  
                     conn.setDoOutput(true);  
                     conn.setDoInput(true);  
                     conn.connect();  
  
                      BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));   
              StringBuffer sb = new StringBuffer();   
              String line;   
  while ((line = br.readLine()) != null)   
                      sb.append(line);   
  
                     text.setText(sb.toString());  
  
             }catch(Exception e){  
                     Log.e(this.getClass().getName(), e.getMessage());  
             }  
  
     }  
  
  private class MyHostnameVerifier implements HostnameVerifier{  
  
  @Override 
  public boolean verify(String hostname, SSLSession session) {  
  // TODO Auto-generated method stub 
  return true;  
                 }  
     }  
  
  private class MyTrustManager implements X509TrustManager{  
  
  @Override 
  public void checkClientTrusted(X509Certificate[] chain, String authType)  
  throws CertificateException {  
  // TODO Auto-generated method stub 
  
                 }  
  
  @Override 
  public void checkServerTrusted(X509Certificate[] chain, String authType)  
  throws CertificateException {  
  // TODO Auto-generated method stub 
  
                 }  
  
  @Override 
  public X509Certificate[] getAcceptedIssuers() {  
  // TODO Auto-generated method stub 
  return null;  
                 }          
     }    
 }  

如果需要验证服务器端证书(这样能够防钓鱼),我是这样做的,还有些问题问大牛:

a. 导出公钥。在浏览器上用https访问tomcat,查看其证书,并另存为一个文件(存成了X.509格式:xxxx.cer)

b. 导入公钥。把xxxx.cer放在Android的assets文件夹中,以方便在运行时通过代码读取此证书,留了两个问题给大牛:

 AssetManager am = context.getAssets();  
 InputStream ins = am.open("robusoft.cer");  
 try {  
  //读取证书 
         CertificateFactory cerFactory = CertificateFactory.getInstance("X.509");  //问1 
         Certificate cer = cerFactory.generateCertificate(ins);  
  //创建一个证书库,并将证书导入证书库 
         KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC");   //问2 
         keyStore.load(null, null);  
         keyStore.setCertificateEntry("trust", cer);  
  return keyStore;  
 } finally {  
         ins.close();  
 }  
 //把咱的证书库作为信任证书库 
 SSLSocketFactory socketFactory = new SSLSocketFactory(keystore);  
 Scheme sch = new Scheme("https", socketFactory, 443);  
 //完工 
 HttpClient mHttpClient = new DefaultHttpClient();  
 mHttpClient.getConnectionManager().getSchemeRegistry().register(sch);  

问1:这里用"PKCS12"不行

答1:PKCS12和JKS是keystore的type,不是Certificate的type,所以X.509不能用PKCS12代替

问2:这里用"JKS"不行。

答2:android平台上支持的keystore type好像只有PKCS12,不支持JKS,所以不能用JKS代替在PKCS12,不过在windows平台上是可以代替的

----------------------------------------------分割线-------------------------------------------------------------------------

1。数据通信时加密,不同平台加密后的结果不同,用的库不同吧(进行相应的修改比较麻烦)

2。采用https,系统自动做好了,简单一些

https与http的通信,在我看来主要的区别在于https多了一个安全验证机制,而Android采用的是X509验证,首先我们需要这重写X509类,建立我们的验证规则、、不过对于特定的项目,我们一般都是无条件信任服务端的,因此我们可以对任何证书都无条件信任(其实本质上我们只是信任了特定url的证书,为了偷懒,才那么选择的)/**

  * 信任所有主机-对于任何证书都不做检查   
  */   
 class MytmArray implements X509TrustManager {    
  public X509Certificate[] getAcceptedIssuers() {    
  // return null;  
  return new X509Certificate[] {};    
     }   
  
  @Override 
  public void checkClientTrusted(X509Certificate[] chain, String authType)    
  throws CertificateException {    
  // TODO Auto-generated method stub  
  
     }   
  
  @Override 
  public void checkServerTrusted(X509Certificate[] chain, String authType)    
  throws CertificateException {    
  // TODO Auto-generated method stub  
  // System.out.println("cert: " + chain[0].toString() + ", authType: "  
  // + authType);  
     }   
 };  
  * 信任所有主机-对于任何证书都不做检查  
  */  
 class MytmArray implements X509TrustManager {  
  public X509Certificate[] getAcceptedIssuers() {  
  // return null; 
  return new X509Certificate[] {};  
     }  
  
  @Override 
  public void checkClientTrusted(X509Certificate[] chain, String authType)  
  throws CertificateException {  
  // TODO Auto-generated method stub 
  
     }  
  
  @Override 
  public void checkServerTrusted(X509Certificate[] chain, String authType)  
  throws CertificateException {  
  // TODO Auto-generated method stub 
  // System.out.println("cert: " + chain[0].toString() + ", authType: " 
  // + authType); 
     }  
 };  

 好了,我们写好了信任规则,接下载就要创建一个主机的信任列表

 static TrustManager[] xtmArray = new MytmArray[] { new MytmArray() };    
  
  /**  
      * 信任所有主机-对于任何证书都不做检查  
      */ 
  private static void trustAllHosts() {    
  // Create a trust manager that does not validate certificate chains  
  // Android 采用X509的证书信息机制  
  // Install the all-trusting trust manager  
  try {    
             SSLContext sc = SSLContext.getInstance("TLS");    
             sc.init(null, xtmArray, new java.security.SecureRandom());    
             HttpsURLConnection   
                     .setDefaultSSLSocketFactory(sc.getSocketFactory());   
  // HttpsURLConnection.setDefaultHostnameVerifier(DO_NOT_VERIFY);//  
  // 不进行主机名确认  
         } catch (Exception e) {    
             e.printStackTrace();   
         }   
     }   
  
  static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {    
  @Override 
  public boolean verify(String hostname, SSLSession session) {    
  // TODO Auto-generated method stub  
  // System.out.println("Warning: URL Host: " + hostname + " vs. "  
  // + session.getPeerHost());  
  return true;    
         }   
     };  
 static TrustManager[] xtmArray = new MytmArray[] { new MytmArray() };  
  
  /** 
      * 信任所有主机-对于任何证书都不做检查 
      */ 
  private static void trustAllHosts() {  
  // Create a trust manager that does not validate certificate chains 
  // Android 采用X509的证书信息机制 
  // Install the all-trusting trust manager 
  try {  
             SSLContext sc = SSLContext.getInstance("TLS");  
             sc.init(null, xtmArray, new java.security.SecureRandom());  
             HttpsURLConnection  
                     .setDefaultSSLSocketFactory(sc.getSocketFactory());  
  // HttpsURLConnection.setDefaultHostnameVerifier(DO_NOT_VERIFY);// 
  // 不进行主机名确认 
         } catch (Exception e) {  
             e.printStackTrace();  
         }  
     }  
  
  static HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {  
  @Override 
  public boolean verify(String hostname, SSLSession session) {  
  // TODO Auto-generated method stub 
  // System.out.println("Warning: URL Host: " + hostname + " vs. " 
  // + session.getPeerHost()); 
  return true;  
         }  
     };  

 上面的都是https通信需要做的几个基本要求,接下载我们要做的就是https的使用啦下面就以get和post为例进行说明,中间还涉及到cookie的使用

 String httpUrl="XXXXX" 
 String result = "";    
         HttpURLConnection http = null;    
         URL url;   
  try {    
             url = new URL(httpUrl);    
  // 判断是http请求还是https请求  
  if (url.getProtocol().toLowerCase().equals("https")) {    
                 trustAllHosts();   
                 http = (HttpsURLConnection) url.openConnection();   
                 ((HttpsURLConnection) http).setHostnameVerifier(DO_NOT_VERIFY);// 不进行主机名确认  
  
             } else {    
                 http = (HttpURLConnection) url.openConnection();   
             }   
             http.setConnectTimeout(10000);// 设置超时时间  
             http.setReadTimeout(50000);    
             http.setRequestMethod("GET");// 设置请求类型为  
             http.setDoInput(true);    
             http.setRequestProperty("Content-Type", "text/xml");    
 //http.getResponseCode());http或https返回状态200还是403  
 BufferedReader in = null;    
  if (obj.getHttpStatus() == 200) {    
                 getCookie(http);   
                 in = new BufferedReader(new InputStreamReader(    
                         http.getInputStream()));   
             } else 
                 in = new BufferedReader(new InputStreamReader(    
                         http.getErrorStream()));   
             result = in.readLine();   
             Log.i("result", result);    
             in.close();   
             http.disconnect();  
 String httpUrl="XXXXX" 
 String result = "";  
         HttpURLConnection http = null;  
         URL url;  
  try {  
             url = new URL(httpUrl);  
  // 判断是http请求还是https请求 
  if (url.getProtocol().toLowerCase().equals("https")) {  
                 trustAllHosts();  
                 http = (HttpsURLConnection) url.openConnection();  
                 ((HttpsURLConnection) http).setHostnameVerifier(DO_NOT_VERIFY);// 不进行主机名确认 
  
             } else {  
                 http = (HttpURLConnection) url.openConnection();  
             }  
             http.setConnectTimeout(10000);// 设置超时时间 
             http.setReadTimeout(50000);  
             http.setRequestMethod("GET");// 设置请求类型为 
             http.setDoInput(true);  
             http.setRequestProperty("Content-Type", "text/xml");  
 //http.getResponseCode());http或https返回状态200还是403 
 BufferedReader in = null;  
  if (obj.getHttpStatus() == 200) {  
                 getCookie(http);  
                 in = new BufferedReader(new InputStreamReader(  
                         http.getInputStream()));  
             } else 
                 in = new BufferedReader(new InputStreamReader(  
                         http.getErrorStream()));  
             result = in.readLine();  
             Log.i("result", result);  
             in.close();  
             http.disconnect();  

 https或http的get请求写好了,哦中间涉及到了一个getCookie的方法,如下:

 /** 得到cookie */ 
  private static void getCookie(HttpURLConnection http) {    
         String cookieVal = null;    
         String key = null;    
         DataDefine.mCookieStore = "";    
  for (int i = 1; (key = http.getHeaderFieldKey(i)) != null; i++) {    
  if (key.equalsIgnoreCase("set-cookie")) {    
                 cookieVal = http.getHeaderField(i);   
                 cookieVal = cookieVal.substring(0, cookieVal.indexOf(";"));    
                 DataDefine.mCookieStore = DataDefine.mCookieStore + cookieVal   
                         + ";";    
             }   
         }   
     }  
 /** 得到cookie */ 
  private static void getCookie(HttpURLConnection http) {  
         String cookieVal = null;  
         String key = null;  
         DataDefine.mCookieStore = "";  
  for (int i = 1; (key = http.getHeaderFieldKey(i)) != null; i++) {  
  if (key.equalsIgnoreCase("set-cookie")) {  
                 cookieVal = http.getHeaderField(i);  
                 cookieVal = cookieVal.substring(0, cookieVal.indexOf(";"));  
                 DataDefine.mCookieStore = DataDefine.mCookieStore + cookieVal  
                         + ";";  
             }  
         }  
     }  

public static Query HttpQueryReturnClass(String httpUrl, String base64) {

         String result = "";    
         Log.i("控制", httpUrl);    
         Query obj = new Query();    
         HttpURLConnection http = null;    
         URL url;   
  try {    
             url = new URL(httpUrl);    
  // 判断是http请求还是https请求  
  if (url.getProtocol().toLowerCase().equals("https")) {    
                 trustAllHosts();   
                 http = (HttpsURLConnection) url.openConnection();   
                 ((HttpsURLConnection) http).setHostnameVerifier(DO_NOT_VERIFY);// 不进行主机名确认  
             } else {    
                 http = (HttpURLConnection) url.openConnection();   
             }   
             http.setConnectTimeout(10000);// 设置超时时间  
             http.setReadTimeout(50000);    
             http.setRequestMethod("POST");// 设置请求类型为post  
             http.setDoInput(true);    
             http.setDoOutput(true);    
             http.setRequestProperty("Content-Type", "text/xml");    
             http.setRequestProperty("Cookie", DataDefine.mCookieStore);    
             DataOutputStream out = new DataOutputStream(http.getOutputStream());    
             out.writeBytes(base64);   
             out.flush();   
             out.close();   
             obj.setHttpStatus(http.getResponseCode());// 设置http返回状态200还是403  
             BufferedReader in = null;    
  if (obj.getHttpStatus() == 200) {    
                 getCookie(http);   
                 in = new BufferedReader(new InputStreamReader(    
                         http.getInputStream()));   
             } else 
                 in = new BufferedReader(new InputStreamReader(    
                         http.getErrorStream()));   
             result = in.readLine();// 得到返回结果  
             in.close();   
             http.disconnect();   
         } catch (Exception e) {    
  // TODO Auto-generated catch block  
             e.printStackTrace();   
         }   
 }  
         String result = "";  
         Log.i("控制", httpUrl);  
         Query obj = new Query();  
         HttpURLConnection http = null;  
         URL url;  
  try {  
             url = new URL(httpUrl);  
  // 判断是http请求还是https请求 
  if (url.getProtocol().toLowerCase().equals("https")) {  
                 trustAllHosts();  
                 http = (HttpsURLConnection) url.openConnection();  
                 ((HttpsURLConnection) http).setHostnameVerifier(DO_NOT_VERIFY);// 不进行主机名确认 
             } else {  
                 http = (HttpURLConnection) url.openConnection();  
             }  
             http.setConnectTimeout(10000);// 设置超时时间 
             http.setReadTimeout(50000);  
             http.setRequestMethod("POST");// 设置请求类型为post 
             http.setDoInput(true);  
             http.setDoOutput(true);  
             http.setRequestProperty("Content-Type", "text/xml");  
             http.setRequestProperty("Cookie", DataDefine.mCookieStore);  
             DataOutputStream out = new DataOutputStream(http.getOutputStream());  
             out.writeBytes(base64);  
             out.flush();  
             out.close();  
             obj.setHttpStatus(http.getResponseCode());// 设置http返回状态200还是403 
             BufferedReader in = null;  
  if (obj.getHttpStatus() == 200) {  
                 getCookie(http);  
                 in = new BufferedReader(new InputStreamReader(  
                         http.getInputStream()));  
             } else 
                 in = new BufferedReader(new InputStreamReader(  
                         http.getErrorStream()));  
             result = in.readLine();// 得到返回结果 
             in.close();  
             http.disconnect();  
         } catch (Exception e) {  
  // TODO Auto-generated catch block 
             e.printStackTrace();  
         }  
 }  

 这里面的base64是我经过base64加密过以后的数据