Android HTTPS SSL双向验证 使用HTTPs
HTTPS和HTTP的区别
1 2 3 4 5 6 7 | 1、https协议需要到ca申请证书,一般免费证书很少,需要交费。 2、http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。 3、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。 4、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。 |
二、SSL功能
1 2 3 4 5 6 7 8 | 1)客户对服务器的身份认证: SSL服务器允许客户的浏览器使用标准的公钥加密技术和一些可靠的认证中心(CA)的证书,来确认服务器的合法性。 2)服务器对客户的身份认证: 也可通过公钥技术和证书进行认证,也可通过用户名,password来认证。 3)建立服务器与客户之间安全的数据通道: SSL要求客户与服务器之间的所有发送的数据都被发送端加密、接收端解密,同时还检查数据的完整性。 |
SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层:
SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。
SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
三、生成密钥库和证书
可参考以下密钥生成脚本,根据实际情况做必要的修改,其中需要注意的是:服务端的密钥库参数“CN”必须与服务端的IP地址相同,否则会报错,客户端的任意。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 1、生成服务器证书库 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 2、生成客户端证书库 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 3、从客户端证书库中导出客户端证书 keytool -export -v -alias client -keystore D:\ssl\client.p12 -storetype PKCS12 -storepass 123456 -rfc -file D:\ssl\client.cer 4、从服务器证书库中导出服务器证书 keytool -export -v -alias server -keystore D:\ssl\server.keystore -storepass 123456 -rfc -file D:\ssl\server.cer 5、生成客户端信任证书库(由服务端证书生成的证书库) keytool -import -v -alias server -file D:\ssl\server.cer -keystore D:\ssl\client.truststore -storepass 123456 6、将客户端证书导入到服务器证书库(使得服务器信任客户端证书) keytool -import -v -alias client -file D:\ssl\client.cer -keystore D:\ssl\server.keystore -storepass 123456 7、查看证书库中的全部证书 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 服务端/客户端双向认证(一)
四、Android端SSL认证请求
一般客户端验证SSL有两种方式,一种是通过SSLSocketFactory方式创建,需要设置域名及端口号(适应于HttpClient请求方式),一种是通过SSLContext方式创建(适用于HttpsURLConnection请求方式).
1、下面给出SslSocketFactory方式进行SSL认证的客户端代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | 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; } |
2、下面给出SSLContext方式进行SSL认证的客户端代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | 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
本文转自yunlielai51CTO博客,原文链接:http://blog.51cto.com/4925054/1949641,如需转载请自行联系原作者
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Failed to install weibo4android.apk on device 'emulator-5554': timeout...
以前遇到过这种问题当时的做法是kill掉虚拟机的进程 @echooff taskkill/f/imemulator-arm.exe 总这样做很浪费时间,下面的方法可以解决这个问题 在window->preferences->Android->DDMS->ADBconnectiontimeout(ms): 将这个值设置的大一些,默认为5000,我设置成500000,然后就OK了。 本文转自sucre03 51CTO博客,原文链接:http://blog.51cto.com/sucre/629497,如需转载请自行联系原作者
- 下一篇
Eclipse搭建Android开发环境(安装ADT,Android4.4.2)
使用Eclipse做Android开发,需要先在Eclipse上安装ADT(Android Development Tools)插件。 1.安装JDK 1.7 JDK官网http://www.oracle.com/technetwork/java/javase/downloads/index.html,下载JDK7软件包,我安装的是1.7.0_55版本。安装完JDK后,配置下JDK环境即可。 2.下载Eclipse Eclipse官网:http://www.eclipse.org/downloads/,我下载的eclipse-java-kepler-SR2-win32.zip,解压到自己的目录下即可使用,无需安装。双击eclipse.exe即可运行。 3.安装Android SDK 去官网:http://developer.android.com/sdk/index.html下载adt-bundle-windows-x86-20140321.zip 这个安装包中包含了SDK和Eclipse,安装包自带的Eclipse可以直接进行Android开发,无需配置。这里,只使用解压后的sdk文...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7设置SWAP分区,小内存服务器的救世主
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Hadoop3单机部署,实现最简伪集群
- Mario游戏-低调大师作品
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Red5直播服务器,属于Java语言的直播服务器