HTTPS和HTTP的区别html
一、https协议须要到ca申请证书,通常免费证书不多,须要交费。 二、http是超文本传输协议,信息是明文传输,https 则是具备安全性的ssl加密传输协议。 三、http和https使用的是彻底不一样的链接方式,用的端口也不同,前者是80,后者是443。 四、http的链接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
1)客户对服务器的身份认证: SSL服务器容许客户的浏览器使用标准的公钥加密技术和一些可靠的认证中心(CA)的证书,来确认服务器的合法性。 2)服务器对客户的身份认证: 也可经过公钥技术和证书进行认证,也可经过用户名,password来认证。 3)创建服务器与客户之间安全的数据通道: SSL要求客户与服务器之间的全部发送的数据都被发送端加密、接收端解密,同时还检查数据的完整性。
SSL协议位于TCP/IP协议与各类应用层协议之间,为数据通信提供安全支持。SSL协议可分为两层:java
SSL记录协议(SSL Record Protocol):它创建在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。android
SSL握手协议(SSL Handshake Protocol):它创建在SSL记录协议之上,用于在实际的数据传输开始前,通信双方进行身份认证、协商加密算法、交换加密密钥等。算法
可参考如下密钥生成脚本,根据实际状况作必要的修改,其中须要注意的是:服务端的密钥库参数“CN”必须与服务端的IP地址相同,不然会报错,客户端的任意。浏览器
一、生成服务器证书库 keytool -validity 365 -genkey -v -alias server -keyalg RSA -keystore D:\ssl\server.keystore -dname "CN=127.0.0.1,OU=rongyiwang,O=rongyiwang,L=Shanghai,ST=Shanghai,c=cn" -storepass 123456 -keypass 123456 二、生成客户端证书库 keytool -validity 365 -genkeypair -v -alias client -keyalg RSA -storetype PKCS12 -keystore D:\ssl\client.p12 -dname "CN=client,OU=rongyiwang,O=rongyiwang,L=Shanghai,ST=Shanghai,c=cn" -storepass 123456 -keypass 123456 三、从客户端证书库中导出客户端证书 keytool -export -v -alias client -keystore D:\ssl\client.p12 -storetype PKCS12 -storepass 123456 -rfc -file D:\ssl\client.cer 四、从服务器证书库中导出服务器证书 keytool -export -v -alias server -keystore D:\ssl\server.keystore -storepass 123456 -rfc -file D:\ssl\server.cer 五、生成客户端信任证书库(由服务端证书生成的证书库) keytool -import -v -alias server -file D:\ssl\server.cer -keystore D:\ssl\client.truststore -storepass 123456 六、将客户端证书导入到服务器证书库(使得服务器信任客户端证书) keytool -import -v -alias client -file D:\ssl\client.cer -keystore D:\ssl\server.keystore -storepass 123456 七、查看证书库中的所有证书 keytool -list -keystore D:\ssl\server.keystore -storepass 123456
经过上面的步骤生成的证书,客户端须要用到的是client.p12(客户端证书,用于请求的时候给服务器来验证身份之用)和client.truststore(客户端证书库,用于验证服务器端身份,防止钓鱼)这两个文件.
安全
其中安卓端的证书类型必需要求是BKS类型,具体生成能够参考这个create a bks bouncycastle,这里涉及到这个JARbcprov-ext-jdk15on-152.jar文件.服务器
如下只给出Android端的请求,具体服务器端的配置能够参考这篇博客-->Java Tomcat SSL 服务端/客户端双向认证(一)网络
通常客户端验证SSL有两种方式,一种是经过SSLSocketFactory方式建立,须要设置域名及端口号(适应于HttpClient请求方式),一种是经过SSLContext方式建立(适用于HttpsURLConnection请求方式).
一、下面给出SslSocketFactory方式进行SSL认证的客户端代码数据结构
private static final String KEY_STORE_TYPE_BKS = "bks";//证书类型 固定值 private static final String KEY_STORE_TYPE_P12 = "PKCS12";//证书类型 固定值 private static final String KEY_STORE_CLIENT_PATH = "client.p12";//客户端要给服务器端认证的证书 private static final String KEY_STORE_TRUST_PATH = "client.truststore";//客户端验证服务器端的证书库 private static final String KEY_STORE_PASSWORD = "123456";// 客户端证书密码 private static final String KEY_STORE_TRUST_PASSWORD = "123456";//客户端证书库密码 /** * 获取SslSocketFactory * * @param context 上下文 * @return SSLSocketFactory */ public static SSLSocketFactory getSslSocketFactory(Context context) { try { // 服务器端须要验证的客户端证书 KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12); // 客户端信任的服务器端证书 KeyStore trustStore = KeyStore.getInstance(KEY_STORE_TYPE_BKS); InputStream ksIn = context.getResources().getAssets().open(KEY_STORE_CLIENT_PATH); InputStream tsIn = context.getResources().getAssets().open(KEY_STORE_TRUST_PATH); try { keyStore.load(ksIn, KEY_STORE_PASSWORD.toCharArray()); trustStore.load(tsIn, KEY_STORE_TRUST_PASSWORD.toCharArray()); } catch (Exception e) { e.printStackTrace(); } finally { try { ksIn.close(); } catch (Exception ignore) { } try { tsIn.close(); } catch (Exception ignore) { } } return new SSLSocketFactory(keyStore, KEY_STORE_PASSWORD, trustStore); } catch (KeyManagementException | UnrecoverableKeyException | KeyStoreException | FileNotFoundException | NoSuchAlgorithmException | ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 获取SSL认证须要的HttpClient * * @param context 上下文 * @param port 端口号 * @return HttpClient */ public static HttpClient getSslSocketFactoryHttp(Context context, int port) { HttpClient httpsClient = new DefaultHttpClient(); SSLSocketFactory sslSocketFactory = getSslSocketFactory(context); if (sslSocketFactory != null) { Scheme sch = new Scheme("https", sslSocketFactory, port); httpsClient.getConnectionManager().getSchemeRegistry().register(sch); } return httpsClient; }
二、下面给出SSLContext方式进行SSL认证的客户端代码ide
private static final String KEY_STORE_TYPE_BKS = "bks";//证书类型 固定值 private static final String KEY_STORE_TYPE_P12 = "PKCS12";//证书类型 固定值 private static final String KEY_STORE_CLIENT_PATH = "client.p12";//客户端要给服务器端认证的证书 private static final String KEY_STORE_TRUST_PATH = "client.truststore";//客户端验证服务器端的证书库 private static final String KEY_STORE_PASSWORD = "123456";// 客户端证书密码 private static final String KEY_STORE_TRUST_PASSWORD = "123456";//客户端证书库密码 /** * 获取SSLContext * * @param context 上下文 * @return SSLContext */ private static SSLContext getSSLContext(Context context) { try { // 服务器端须要验证的客户端证书 KeyStore keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12); // 客户端信任的服务器端证书 KeyStore trustStore = KeyStore.getInstance(KEY_STORE_TYPE_BKS); InputStream ksIn = context.getResources().getAssets().open(KEY_STORE_CLIENT_PATH); InputStream tsIn = context.getResources().getAssets().open(KEY_STORE_TRUST_PATH); try { keyStore.load(ksIn, KEY_STORE_PASSWORD.toCharArray()); trustStore.load(tsIn, KEY_STORE_TRUST_PASSWORD.toCharArray()); } catch (Exception e) { e.printStackTrace(); } finally { try { ksIn.close(); } catch (Exception ignore) { } try { tsIn.close(); } catch (Exception ignore) { } } SSLContext sslContext = SSLContext.getInstance("TLS"); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(trustStore); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509"); keyManagerFactory.init(keyStore, KEY_STORE_PASSWORD.toCharArray()); sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); return sslContext; } catch (Exception e) { Log.e("tag", e.getMessage(), e); } return null; } /** * 获取SSL认证须要的HttpClient * * @param context 上下文 * @return OkHttpClient */ public static OkHttpClient getSSLContextHttp(Context context) { OkHttpClient client = new OkHttpClient(); SSLContext sslContext = getSSLContext(context); if (sslContext != null) { client.setSslSocketFactory(sslContext.getSocketFactory()); } return client; } /** * 获取HttpsURLConnection * * @param context 上下文 * @param url 链接url * @param method 请求方式 * @return HttpsURLConnection */ public static HttpsURLConnection getHttpsURLConnection(Context context, String url, String method) { URL u; HttpsURLConnection connection = null; try { SSLContext sslContext = getSSLContext(context); if (sslContext != null) { u = new URL(url); connection = (HttpsURLConnection) u.openConnection(); connection.setRequestMethod(method);//"POST" "GET" connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); connection.setRequestProperty("Content-Type", "binary/octet-stream"); connection.setSSLSocketFactory(sslContext.getSocketFactory()); connection.setConnectTimeout(30000); } } catch (Exception e) { e.printStackTrace(); } return connection; }
参考:http://blog.csdn.net/u012874222/article/details/50339259
//使用https传输:
参考:http://blog.csdn.net/haoaoo/article/details/54614875
http://blog.csdn.net/dlx2chengyt/article/details/53081329