http 和 https请求,证书生成

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

public class MyX509TrustManager implements X509TrustManager {

	@Override
	public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
		// TODO Auto-generated method stub
		// 检查客户端证书
	}

	@Override
	public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
		// TODO Auto-generated method stub
		// 检查服务器端证书  
	}

	@Override
	public X509Certificate[] getAcceptedIssuers() {
		// TODO Auto-generated method stub
		// 返回受信任的X509证书数组 
		return null;
	}

}

X509证书信任管理器类

public static String  httpPostUtil(String pathUrl, JSONObject content) {
		boolean isHttps = true;
		String strResult = "";
		DataOutputStream out = null;
		BufferedReader reader = null;
		
		if(pathUrl.toLowerCase().startsWith("https:")){
			isHttps = true;
		}else{
			isHttps = false;
		}
		
		if(isHttps){
			SSLContext ctx = null;
	        try {
	            ctx = SSLContext.getInstance("TLS");
	            ctx.init(new KeyManager[0], new TrustManager[] { new MyX509TrustManager() }, new SecureRandom());
	        } catch (KeyManagementException e) {
	            e.printStackTrace();
	        } catch (NoSuchAlgorithmException e) {
	            e.printStackTrace();
	        }
	        SSLSocketFactory ssf = ctx.getSocketFactory();
	        HttpsURLConnection httpsConn = null;
	        try{
		        URL url = new URL(pathUrl);
		        httpsConn = (HttpsURLConnection) url.openConnection();
		        httpsConn.setSSLSocketFactory(ssf);
		        httpsConn.setHostnameVerifier(new HostnameVerifier() {
		            @Override
		            public boolean verify(String arg0, SSLSession arg1) {
		                return true;
		            }
		        });
		        httpsConn.setRequestMethod("POST");
		        httpsConn.setDoInput(true);
		        httpsConn.setDoOutput(true);
		        httpsConn.setConnectTimeout(6000);
		        httpsConn.setReadTimeout(6000);
		        
		        httpsConn.setRequestProperty("Connection", "keep-alive");  //设置连接的状态
		        httpsConn.setRequestProperty("Transfer-Encoding", "chunked");//设置传输编码
		        httpsConn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
		        
		        out = new DataOutputStream(httpsConn.getOutputStream());
		        out.write(content.toString().getBytes("UTF-8"));
		        
		        out.flush();
				
		        out.close();
		        StringBuffer stringbuffer = new StringBuffer();
		        if (httpsConn.getResponseCode()==200){
		        	reader = new BufferedReader(new InputStreamReader(httpsConn.getInputStream()));
		        	String line="";
		        	while ((line = reader.readLine()) != null) {
		        		stringbuffer.append(line);
					}
		        	strResult = stringbuffer.toString();
		        	reader.close();
		        }else{

		        }
		        httpsConn.disconnect();
		        
		        
	        }catch (Exception e) {
				// TODO: handle exception
	        	if(httpsConn!=null){
	        		httpsConn.disconnect();
	        	}
			}
		}else{
			URL postUrl = null;
			HttpURLConnection connection = null;
			try {
				postUrl = new URL(pathUrl);
				connection = (HttpURLConnection) postUrl.openConnection();
				
				connection.setDoOutput(true);// http正文内,因此需要设为true, 默认情况下是false;
	            connection.setDoInput(true);
	            connection.setConnectTimeout(6000);
	            connection.setReadTimeout(6000);
				
				connection.setRequestMethod("POST");

		        connection.setRequestProperty("Connection", "keep-alive"); 
		        connection.setRequestProperty("Transfer-Encoding", "chunked");
		        connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");

		        out = new DataOutputStream(connection.getOutputStream());
		        out.write(content.toString().getBytes("UTF-8"));
		        
		        out.flush();
				
		        out.close();
		        StringBuffer stringbuffer = new StringBuffer();
		        if (connection.getResponseCode()==200){
		        	reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
		        	String line="";
		        	while ((line = reader.readLine()) != null) {
		        		stringbuffer.append(line);
					}
		        	strResult = stringbuffer.toString();
		        	reader.close();
		        }else{

		        }
		        connection.disconnect();
			} catch (MalformedURLException e4) {
				// TODO Auto-generated catch block
				e4.printStackTrace();
				if(connection!=null){
					connection.disconnect();
	        	}
			}catch (IOException e3) {
				e3.printStackTrace();
				if(connection!=null){
					connection.disconnect();
	        	}
			}
		}
		
		logger.info("strResult="+strResult);
    	return strResult;
	}

生成证书

1:什么是HTTPS?

HTTPS其实是有两部分组成:HTTP + SSL / TLS,

也就是在HTTP上又加了一层处理加密信息的模块,并且会进行身份的验证。

问题:

Firebug和postman之类的浏览器调试工具,为什么获取到的是明文?

解答:

SSL是对传输的数据进行加密,针对的是传输过程的安全。 

firebug之类的浏览器调试工具,

因为他们得到的是客户端加密之前/解密之后的数据,因此是明文的。

2:什么是自签名证书?

就是自己生成的证书,并不是官方生成的证书。

除非是很正式的项目,否则使用自己签发的证书即可,因为官方生成证书是要花钱滴。

使用JDK自带工具KeyTool 生成自签发证书!

第一步:为服务器生成证书

需要使用jdk自带的keytool来生成证书,如果已配置java环境变量,在任何目录启动命令行输入以下命令即可,若未配置java环境变量,则需要到jdk安装目录bin文件夹下启动命令行;

使用keytool命令生成证书:

keytool 

-genkey 

-alias tomcat(别名) 

-keypass 123456(别名密码) 

-keyalg RSA(算法) 

-keysize 1024(密钥长度) 

-validity 365(有效期,天单位) 

-keystore c:/tomcat.keystore(指定生成证书的位置和证书名称) 

-storepass 123456(获取keystore信息的密码)

C:\Program Files\Java\jdk1.7.0_75\bin>keytool -genkey -alias appsys -keypass 123456 -keyalg RSA -keysize 1024 -validity 365 -keystore c:/cer/appsys.keystore -storepass 123456
您的名字与姓氏是什么?
  [Unknown]:  test
您的组织单位名称是什么?
  [Unknown]:  test
您的组织名称是什么?
  [Unknown]:  test
您所在的城市或区域名称是什么?
  [Unknown]:  sz
您所在的省/市/自治区名称是什么?
  [Unknown]:  gd
该单位的双字母国家/地区代码是什么?
  [Unknown]:  china
CN=webcm, OU=webcm, O=webcm, L=sz, ST=gd, C=china是否正确?
  [否]:  y

 

第二步:为客户端生成证书

为浏览器生成证书,以便让服务器来验证它。

为了能将证书顺利导入至IE和Firefox,证书格式应该是PKCS12,

因此,使用如下命令生成:

keytool 

-genkey 

-alias client 

-keypass 123456

-keyalg RSA 

-storetype PKCS12 

-keypass 123456 

-storepass 123456 

-keystore c:/client.p12

C:\Program Files\Java\jdk1.7.0_75\bin>keytool -genkey -alias appclient -keypass 123456 -keyalg RSA -keysize 1024 -validity 365 -storetype PKCS12 -keystore c:/cer/appclient.p12 -storepass 123456
您的名字与姓氏是什么?
  [Unknown]:  test
您的组织单位名称是什么?
  [Unknown]:  test
您的组织名称是什么?
  [Unknown]:  test
您所在的城市或区域名称是什么?
  [Unknown]:  sz
您所在的省/市/自治区名称是什么?
  [Unknown]:  gd
该单位的双字母国家/地区代码是什么?
  [Unknown]:  china
CN=webcm, OU=webcm, O=webcm, L=sz, ST=gd, C=china是否正确?
  [否]:  y

 

第三步:让服务器信任客户端证书

1、

由于不能直接将PKCS12格式的证书库导入,

必须先把客户端证书导出为一个单独的CER文件,使用如下命令:

keytool -export -alias appclient -keystore c:/cer/appclient.p12 -storetype PKCS12 -keypass 123456 -file c:/cer/appclient.cer

注意:

Keypass:指定CER文件的密码,但会被忽略,而要求重新输入

2、

将该文件导入到服务器的证书库,添加为一个信任证书:

keytool -import -v -file c:/cer/appclient.cer -keystore c:/cer/appsys.keystore -storepass 123456

完成之后通过list命令查看服务器的证书库,

可以看到两个证书,一个是服务器证书,一个是受信任的客户端证书:

keytool -list -v -keystore c:/cer/appsys.keystore

第四步:让客户端信任服务器证书

1、

由于是双向SSL认证,客户端也要验证服务器证书,

因此,必须把服务器证书添加到浏览器的“受信任的根证书颁发机构”。

由于不能直接将keystore格式的证书库导入,

必须先把服务器证书导出为一个单独的CER文件,使用如下命令:

keytool -keystore c:/cer/appsys.keystore -export -alias appsys -file c:/cer/appserver.cer

2、

双击appserver.cer文件,按照提示安装证书,

将证书填入到“受信任的根证书颁发机构”。

填入方法:

打开浏览器   - 工具  -  internet选项-内容- 证书-把中级证书颁发机构里的www.localhost.com(该名称即时你前面生成证书时填写的名字与姓氏)证书导出来-再把导出来的证书导入  受信任的根颁发机构  就OK了。

 

步骤五:配置Tomcat服务器

<Connector port="8081" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
     scheme="https" secure="true" clientAuth="false" sslProtocol="TLS"
    keystoreFile="/home/apache-tomcat/te.keystore" keystorePass="123456"
    truststoreFile="/home/apache-tomcat/te.keystore"
    truststorePass="123456" connectionTimeout="20000"
        redirectPort="8443" useBodyEncodingForURI="true" URIEncoding="UTF-8" />

属性说明:

clientAuth:设置是否双向验证,默认为false,设置为true代表双向验证

keystoreFile:服务器证书文件路径

keystorePass:服务器证书密码

truststoreFile:用来验证客户端证书的根证书,此例中就是服务器证书

truststorePass:根证书密码

注意:

① 设置clientAuth属性为True时,需要手动导入客户端证书才能访问。

② 要访问https请求 需要访问8443端口,访问http请求则访问Tomcat默认端口(你自己设置的端口,默认8080)即可。

 同时也支持http需要再加上下面配置:

<Connector
        port="8082"
        protocol="HTTP/1.1"
        connectionTimeout="20000"
        redirectPort="8443" useBodyEncodingForURI="true" URIEncoding="UTF-8" />

然后重启tomcat,使用http,https访问成功。

小知识:

强制 https 访问

在 tomcat /conf/web.xml 中的 </welcome- file-list> 后面加上这

<login-config>    
<!-- Authorization setting for SSL -->    
<auth-method>CLIENT-CERT</auth-method>    
<realm-name>Client Cert Users-only Area</realm-name>    
</login-config>    
<security-constraint>    
<!-- Authorization setting for SSL -->    
<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的访问地址也会自动转换为https

如不能访问,先查看端口是否被禁用了。

注:浏览器不能同时访问HTTP,HTTPS,需要关闭浏览器后再访问另地址。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值