1.生成keystore
打开cmd,输入(jdk环境变量当然是配置好的):
keytool -genkey -alias tomcat -keyalg RSA –validity 60 -keystore D:\tomcat.keystore
cmd输出:
输入keystore密码:******
再次输入新密码:******
您的名字与姓氏是什么?
[Unknown]: localhost
您的组织单位名称是什么?
[Unknown]: it
您的组织名称是什么?
[Unknown]: dev
您所在的城市或区域名称是什么?
[Unknown]: hz
您所在的州或省份名称是什么?
[Unknown]: zj
该单位的两字母国家代码是什么
[Unknown]: CN
CN=localhost, OU=it, O=dev, L=hz, ST=zj, C=CN
[否]: Y
输入<tomcat>的主密码
(如果和 keystore 密码相同,按回车):
参数说明:
-genkey表示生成密钥
-validity指定证书有效期,这里是60天
-alias指定别名,这里是tomcat
-keyalg指定算法,这里是RSA
-keystore指定存储位置,这里是D:\ tomcat.keystore
使用的自定义密码为 123456
*其中 您的名字与姓氏是什么? localhost是网站的域名或者ip,根据实际情况填写。否者会出现证书上的名称无效;
2.配置tomcat服务器支持SSL
将生成的 tomcat.keystore文件,放到%TOMCAT_HOME%/conf目录中(其他也OK).
说明: 修改%TOMCAT_HOME%/conf/server.xml,新增Connector(原注释里有): Code: |
<Connector SSLEnabled="true" URIEncoding="UTF-8" clientAuth="false" keystoreFile="conf/tomcat.keystore" keystorePass="123456" maxThreads="150" port="8443" protocol="HTTP/1.1" scheme="https" secure="true" sslProtocol="TLS" /> |
这样你的tomcat就支持https访问了;
属性说明:
port: 这个port属性(默认值是8443)是 TCP/IP端口数码,Tomcat在其上监听安全连接。你可以把它更改成任何你愿意要的数值(如默认的https通信,数目是443)。不过,在许多操作系统中,要想在比1024小的端口数码上运行Tomcat,需要特殊的设置(它超出了这个文档资料的范围)。
redirectPort: 如果你在这里更改端口数值,你还必须更改在non-SSL连接器上的redirectPort 这个属性特定的值。这允许Tomcat自动地redirect那些试图访问有安全限制页面的用户,指明根据 Servlet 2.4 Specification要求,SSL是必需的
clientAuth: 如果你想要Tomcat要求所有的SSL客户在使用这个socket时出示用户认证书,把这个值设定为 true 。如果你想要Tomcat要求出示用户认证书,但是如果没有认证书也可以, 就把这个值设定为want 。
keystoreFile: 如果你产生的keystore文件不在Tomcat期望的默认地方(一个叫做.keystore 的文件在Tomcat运行的主目录),就添加这个属性。你可以指定一个绝对路径名称, 或者一个由$CATALINA_BASE环境变量而派生的相对路径名称。
keystorePass: 如果你使用一个不同的keystore(以及认证书)密码,而不是Tomcat期望的密码 (就是changeit),添加这个元素。
keystoreType: 如果使用一个PKCS12 keystore的话,就添加这个element。 有效的值是JKS 和 PKCS12
sslProtocol: 要在这个socket上被使用的加密/解密协定。如果你在使用Sun的JVM,我们不提倡更改 这个值。据报道,TLS协定的IBM's 1.4.1 实现与一些通用的浏览器不兼容。 如果是这样,就使用value SSL
ciphers: 这个socket允许使用的由逗号分隔开的加密密码列单。默认的情况下,任何可用的密码都允许被使用。
algorithm: 可用的X509算法。默认是Sun的实现( SunX509 )。 对于IBM JVMs,你应该使用值 IbmX509。对于其他卖主,查阅JVM文档资料来 找正确的值。
truststoreFile: 用来验证用户认证书的TrustStore文件。
truststorePass: 访问TrustStore的密码。默认值就是keystorePass的值。
truststoreType: 如果你在使用与KeyStore不同格式的TrustStore,添加这个元素。 合法的值是JKS和PKCS12
keyAlias: 如果 keystore 里面有多个 key,你可以为用这个选项为加入的 key 起一个名字。 如果没有指定名字,使用时 keystore 内的第一个 key 将会被使用
3.用浏览器访问应用
输入:https://localhost:8484/Struts2/
你会发现你的应用已经处于SLL安全通道中了.
4.用httpclient访问https
Code: |
/**
*
*/
package com.wxl.http;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
/**
* @author wangxl
*
*/
public class HttpClientSSLTest {
private static String url = "https://localhost:8484/Struts2/Ajax/serivceJ.action";
private static String keyStorePath = "d:\\tomcat.keystore";
private static String keyStorePassWord = "888888";
private static int port = 8484;
/**
* @param args
* @throws IOException
* @throws CertificateException
*/
public static void main(String[] args) {
// 创建默认的httpClient实例
HttpClient client = new DefaultHttpClient();
FileInputStream instream = null;
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
instream = new FileInputStream(new File(keyStorePath));
// 加载keyStore d:\\tomcat.keystore
keyStore.load(instream, keyStorePassWord.toCharArray());
// 创建Socket工厂,将keyStore注入
SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore);
// 创建Scheme
Scheme sch = new Scheme("https", port, socketFactory);
// 注册Scheme
client.getConnectionManager().getSchemeRegistry().register(sch);
// 创建http请求(get方式)
HttpGet getMethod = new HttpGet(url);
System.out.println("----------------------------------------");
System.out.println("Executing request:"
+ getMethod.getRequestLine());
HttpResponse response = client.execute(getMethod);
HttpEntity entity = response.getEntity();
System.out.println("----------------------------------------");
System.out.println("Response header:" + response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: "
+ entity.getContentLength());
System.out.println("Response content:"
+ EntityUtils.toString(entity));
System.out.println("----------------------------------------");
EntityUtils.consume(entity);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
instream.close();
} catch (IOException e) {
e.printStackTrace();
}
// 释放连接
client.getConnectionManager().shutdown();
}
}
}
服务器端的action: /**
*
*/
package com.wxl.action;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
* @author wangxl
*
*/
public class TestAction extends ActionSupport {
public void serivceJ() throws Exception {
try {
HttpServletResponse response = ServletActionContext.getResponse();
HttpServletRequest request = ServletActionContext.getRequest();
response.setCharacterEncoding("UTF-8");
String type = request.getParameter("type");
String c = "none";
if (type != null && !"".equals(type)) {
if (type.equalsIgnoreCase("car")) {
c = "Hello:给你一辆宝马";
} else if (type.equalsIgnoreCase("house")) {
c = "Hello:给你一栋别墅";
}
}
response.getWriter().write(c);
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行结果: ---------------------------------------- Executing request:GET https://localhost:8484/Struts2/Ajax/serivceJ.action HTTP/1.1 ---------------------------------------- Response header:HTTP/1.1 200 OK Response content length: 4 Response content:none ----------------------------------------
|
到此,一个完整的httpClient 访问https的流程就走OK了;
注意:生成keyStore的jdk和myEclipse的jdk要一致.否则可能出现错误;