From: http://my.oschina.net/jjface/blog/339144
概述: 客户端,浏览器或者使用http协议和服务器通信的程序。 如: 客户端通过浏览器访问某一网站时,如果该网站为HTTPS网站,浏览器会自动检测系统中是否存在该网站的信任证书, 如果没有信任证书,浏览器一般会拒绝访问,IE会有一个继续访问的链接,但地址栏是红色,给予用户警示作用, 即客户端验证服务端并不是强制性的,可以没有服务端的信任证书,当然是否继续访问完全取决于用户自己。 如果要去除地址栏的红色警告,需要导入服务端提供的证书到浏览器中。 服务器端,使用http协议提供服务的程序。 服务端需要获取到客户端通过浏览器发送过来的认证证书, 如: 该证书在服务端的证书库中已存在,仅仅是个...
概述:
客户端,浏览器或者使用http协议和服务器通信的程序。如:客户端通过浏览器访问某一网站时,如果该网站为HTTPS网站,浏览器会自动检测系统中是否存在该网站的信任证书,如果没有信任证书,浏览器一般会拒绝访问,IE会有一个继续访问的链接,但地址栏是红色,给予用户警示作用,即客户端验证服务端并不是强制性的,可以没有服务端的信任证书,当然是否继续访问完全取决于用户自己。如果要去除地址栏的红色警告,需要导入服务端提供的证书到浏览器中。服务器端,使用http协议提供服务的程序。服务端需要获取到客户端通过浏览器发送过来的认证证书,如:该证书在服务端的证书库中已存在,仅仅是个匹配过程,匹配成功即通过认证,可继续访问网站资源,反之则无法显示网页。基本逻辑:1、生成服务端密钥库并导出证书.2、生成客户端密钥库并导出证书.3、根据服务端密钥库生成客户端信任的证书.4、将客户端证书导入服务端密钥库.5、将服务端证书导入浏览器.源码下载地址:
生成密钥库和证书:因使用java环境,下面使用jdk下面的keytool工具来生成相应的密钥库和证书下面的命令是在windows 7 下面测试通过的,可以直接复制使用1、创建目录,如d:/sslDemo2、使用资源管理进入d:/sslDemo,按住shift+右键,弹出菜单,选择"在此处打开命令行".3、服务器端相关操作3.1、生成服务器证书库keytool -validity 36500 -genkey -v -alias server -keyalg RSA -keystore server.keystore -dname "CN=www.itjoyee.com,OU=itjoyee.com,O=itjoyee.com,L=Wuhan,ST=HuBei,c=cn" -storepass 123456 -keypass 123456注: 服务器证书库参数“CN”必须与服务端的IP地址相同,否则会报错,客户端的任意。3.2、从服务器证书库中导出服务器证书keytool -export -v -alias server -keystore server.keystore -storepass 123456 -rfc -file server.cer3.3、生成客户端信任证书库(由服务端证书生成的证书库,客户端使用此证书验证服务端来源可靠)keytool -import -v -alias server -file server.cer -keystore client.truststore -storepass 123456 -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider注:-storetype BKS 是生成上面可以识别的格式,如果不指定jdk默认生成的格式是JKS.-provider org.bouncycastle.jce.provider.BouncyCastleProvider,需要下载jar包bcprov-jdk16-1.46.jar放到jdk1.7.0_65\jre\lib\ext\目录下.注意需要jdk16,其他的版本android下面有版本不匹配的问题.4、客户端相关操作4.1、生成客户端证书库keytool -validity 36500 -genkeypair -v -alias client -keyalg RSA -storetype PKCS12 -keystore client.p12 -dname "CN=clients.itjoyee.com,OU=jiajianfa,O=jiajianfa,L=Wuhan,ST=HuBei,c=cn" -storepass 123456 -keypass 1234564.2、从客户端证书库中导出客户端证书keytool -export -v -alias client -keystore client.p12 -storetype PKCS12 -storepass 123456 -rfc -file client.cer注:客户端证书可以产生多个.4.3、将客户端证书导入到服务器证书库(使得服务器信任客户端证书,服务器端用此验证客户端的合法性)keytool -import -v -alias client -file client.cer -keystore server.keystore -storepass 1234564.4、查看服务端证书中信任的客户端证书keytool -list -keystore server.keystore -storepass 1234565、服务器端配置由于使用tomcat,下面使用tomcat做为实例配置.5.1、在tomcat安装目录下新建key目录,将上面生成的server.keystore复制过去.5.2、编辑tomcat安装目录下的conf目录下的server.xml,如:d:\sslDemo\apache-tomcat-7.0.55\conf\server.xml找到Connector,修改如下: 1 2 3 4 5 6 7 | < Connector port = "8444" protocol = "org.apache.coyote.http11.Http11NioProtocol" maxThreads = "150" SSLEnabled = "true" scheme = "https" secure = "true" keystoreFile = "${catalina.base}/key/server.keystore" keystorePass = "123456" clientAuth = "true" sslProtocol = "TLS" truststoreFile = "${catalina.base}/key/server.keystore" truststorePass = "123456" /> |
注:
port配置https访问的端口SSLEnabled="true" 开启https服务scheme="https"secure="true" 开启服务端安全通信,客户端获取服务器端证书keystoreFile="${catalina.base}/key/server.keystore" keystorePass="123456" 服务器证书库clientAuth="true" 开启验证客户端sslProtocol="TLS" 使用的协议truststoreFile="${catalina.base}/key/server.keystore" truststorePass="123456" 服务器证书库(已导入客户端证书)6、测试由于生成证书CN配置的是www.itjoyee.com,故需要修改C:\Windows\System32\drivers\etc\hosts添加192.168.0.50 www.itjoyee.com注:192.168.0.50 为服务器的ip启动tomcat打开浏览器地址栏输入 http://www.itjoyee.com:8080/可以访问地址栏输入https://www.itjoyee.com:8444/访问结果,为无法显示,因为,没有使服务器端生成的信任的客户端证书双击client.p12,输入密码,在此访问https://www.itjoyee.com:8444/此时会有证书相关的提示,点击"确认",接着会提示网站安全证书有问题,点击继续访问,即可进入正常访问页面7、tomcat下的服务强制使用ssl配置已ROOT服务为例,修改D:\sslDemo\apache-tomcat-7.0.55\webapps\ROOT\WEB-INF\web.xml添加 1 2 3 4 5 6 7 8 9 | < security-constraint > < web-resource-collection > < web-resource-name >SSL</ web-resource-name > < url-pattern >/*</ url-pattern > </ web-resource-collection > < user-data-constraint > < transport-guarantee >CONFIDENTIAL</ transport-guarantee > </ user-data-constraint > </ security-constraint > |
打开浏览器
地址栏输入 http://www.itjoyee.com:8080/会有证书相关提示为了方便测试android下双向认证可以用,生成证书的时候把域名换成服务器的ip地址,验证才可以通过1、android app 代码实现 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 79 80 81 82 83 84 85 86 87 88 89 | AsyncTask testTask = new AsyncTask() { @Override protected Object doInBackground(Object... params) { try { HttpClient httpsClient = AppSslApplication.getHttpsClient(MainActivity. this .getBaseContext()); HttpGet httpget = new HttpGet(HTTPS_URL); HttpResponse response = httpsClient.execute(httpget); HttpEntity entity = response.getEntity(); Log.e( "Response status" , response.getStatusLine().toString()); if (entity != null ) { Log.e( "Response" , "Response content length: " + entity.getContentLength()); BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(entity.getContent())); String text; while ((text = bufferedReader.readLine()) != null ) { Log.e( "Response status" , text); } bufferedReader.close(); } httpsClient.getConnectionManager().shutdown(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null ; } }; testTask.execute(); public class HttpClientSslHelper { private static final String KEY_STORE_TYPE_BKS = "bks" ; private static final String KEY_STORE_TYPE_P12 = "PKCS12" ; private static final String SCHEME_HTTPS = "https" ; private static final int HTTPS_PORT = 8444 ; 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" ; private static KeyStore keyStore; private static KeyStore trustStore; public static HttpClient getSslHttpClient(Context pContext) { HttpClient httpsClient = new DefaultHttpClient(); try { // 服务器端需要验证的客户端证书 keyStore = KeyStore.getInstance(KEY_STORE_TYPE_P12); // 客户端信任的服务器端证书 trustStore = KeyStore.getInstance(KEY_STORE_TYPE_BKS); InputStream ksIn = pContext.getResources().getAssets().open(KEY_STORE_CLIENT_PATH); InputStream tsIn = pContext.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) { } } SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore, KEY_STORE_PASSWORD, trustStore); Scheme sch = new Scheme(SCHEME_HTTPS, socketFactory, HTTPS_PORT); httpsClient.getConnectionManager().getSchemeRegistry().register(sch); } catch (KeyManagementException e) { e.printStackTrace(); } catch (UnrecoverableKeyException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return httpsClient; } } |
2、android浏览器实现
1.先把你的CA证书拷贝到你的SD卡里面2.进入手机的"设置"->"位置和安全",最下面有个"从SD卡安装",就是安装证书的。---------暂时没有实现