HttpClient and keytool用法

[b][size=large]JDK工具KEYTOOL常用命令[/size][/b]
-genkey 在用户主目录中创建一个默认文件".keystore",还会产生一个mykey的别名,mykey中包含用户的公钥、私钥和证书
-alias 产生别名
-keystore 指定密钥库的名称(产生的各类信息将不在.keystore文件中
-keyalg 指定密钥的算法
-validity 指定创建的证书有效期多少天
-keysize 指定密钥长度
-storepass 指定密钥库的密码
-keypass 指定别名条目的密码
-dname 指定证书拥有者信息例如: "CN=firstName,OU=org,O=bj,L=bj,ST=gd,C=cn"
-list 显示密钥库中的证书信息 keytool -list -v -keystore 别名 -storepass ....
-v 显示密钥库中的证书详细信息
-export 将别名指定的证书导出到文件 keytool -export -alias 别名 -file 文件名.crt
-file 参数指定导出到文件的文件名
-delete 删除密钥库中某条目 keytool -delete -alias 别名 -keystore sage
-keypasswd 修改密钥库中指定条目口令 keytool -keypasswd -alias 别名 -keypass .... -new .... -storepass ... -keystore 别名
-import 将已签名数字证书导入密钥库 keytool -import -alias 别名 -keystore 证书名-file 文件名(可以加.crt 后缀)

1.服务器中生成证书:(注:生成证书时,CN要和服务器的域名相同,如果在本地测试,则使用localhost)
生成证书
keytool -genkey -keystore 文件名(可包含路径) -keyalg rsa -alias 别名 -validity 有效期
keytool -genkey -alias jboss -keyalg RSA -keystore d:\mykeystore -dname "CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN"
-keystore d:\mykeystore 中的路径和名字有自己制定,提示密码设定也有自己定义例如你可以输入111111.
CN为你的域名
OU为你的组织单位名称
O为你的组织名称
L为你所在的城市名称
S为你所在的省份名称
C为你的国家名称

2 查看证书
keytool -list -v -keystore 路径
keytool -list -v -keystore d:\mykeystore

3 修改密码
keytool -keypasswd -alias 别名 -keypass 旧密码 -new 新密码

4 导出证书,由客户端安装
导出的证书文件是以二进制编码文件,无法用文本编辑器正确显示,可以加上 -rfc参数以一种可打印的编者编码输出。
keytool -export -alias 别名 -keystore 证书名 -rfc -file 文件名(可包含路径)
keytool -export -alias jboss-keystore d:\mykeystore -rfc -file d:\mykeystore.cer (这一步也可以通过浏览器客户端操作前提是服务器已经配置好)

5 客户端配置:为客户端的JVM导入密钥(将服务器下发的证书导入到JVM中)
keytool -import -trustcacerts -alias tomcat -keystore "%JAVA_HOME%/JRE/LIB/SECURITY/CACERTS" -file d:\mycerts.cer -storepass changeit

6 查看时客户端是否安装成功
keytool -list -v -keystore "%JAVA_HOME%/JRE/LIB/SECURITY/CACERTS" -alias tomcat 不指定别名会把"%JAVA_HOME%/JRE/LIB/SECURITY/CACERTS“下的证书都打印出来
7 删除密钥库中的条目
keytool -delete -alias Tomcat -keystore "JAVA_HOME%/JRE/LIB/SECURITY/CACERTS"

以上操作是有关证书的生成和导入
证书导入到我们电脑中的JAVA_HOME%/JRE/LIB/SECURITY/CACERTS密钥库后。客户端就可以在本地通过HttpClient以https的形式访问客户端了,在写httpClient code之前需告诉大家服务器端的配置。
A、 服务器一般是在生成keystore后例如上面的1操作后会整合jboss或tomcat

B、整合JBOSS(jboss-5.1.0.GA)

(一)将产生的mycerts放到JbossHOME\server\default\conf下
(二)打开JbossHOME\server\default\deploy\jbossweb.sar\server.xml,修改如下配置:


Java代码
1.<!-- SSL/TLS Connector configuration using the admin devl guide keystore
2. <Connector port="8443" address="${jboss.bind.address}"
3. maxThreads="100" strategy="ms" maxHttpHeaderSize="8192"
4. emptySessionPath="true"
5. scheme="https" secure="true" clientAuth="false"
6. keystoreFile="${jboss.server.home.dir}/conf/mycerts"
7. keystorePass="rmi+ssl" sslProtocol = "TLS" />
8. -->
9.
<Connector protocol="HTTP/1.1" SSLEnabled="true"
port="8443" address="${jboss.bind.address}"
scheme="https" secure="true" clientAuth="false"
keystoreFile="${jboss.server.home.dir}/conf/mycerts"
keystorePass="111111" sslProtocol = "TLS" />


此时基本配置已经完成。

C、在myeclipse中新建一个WEB工程keytest,启动JBOSS,浏览器地址栏输入http://localhost:8080/keytest 或 https://localhost:8443/keytest都可访问则表示JBoss配置成功。成功会提示安装证书。
根据提示导出证书xx.cer文件。客户端浏览网址https://id:8443/keytest同样会有提示
不过导出的可能是crt文件在,之后双击根据提示生成cer文件。
D、 操作客户端配置:为客户端的JVM导入密钥(将服务器下发的证书即生成的cer文件导入到JVM中)
keytool -import -trustcacerts -alias tomcat -keystore "%JAVA_HOME%/JRE/LIB/SECURITY/CACERTS" -file d:\XX.cer -storepass changeit.
之后就可以在客户端代码code了
E、HttpClient 基本功能的使用



GET 方法

使用 HttpClient 需要以下 6 个步骤:

1. 创建 HttpClient 的实例

2. 创建某种连接方法的实例,在这里是 GetMethod。在 GetMethod 的构造函数中传入待连接的地址

3. 调用第一步中创建好的实例的 execute 方法来执行第二步中创建好的 method 实例

4. 读 response

5. 释放连接。无论执行方法是否成功,都必须释放连接

6. 对得到后的内容进行处理

根据以上步骤,我们来编写用GET方法来取得某网页内容的代码。

•大部分情况下 HttpClient 默认的构造函数已经足够使用。 HttpClient httpClient = new HttpClient();



•创建GET方法的实例。在GET方法的构造函数中传入待连接的地址即可。用GetMethod将会自动处理转发过程,如果想要把自动处理转发过程去掉的话,可以调用方法setFollowRedirects(false)。 GetMethod getMethod = new GetMethod("https://id:8443/keytest/list");



•调用实例httpClient的executeMethod方法来执行getMethod。由于是执行在网络上的程序,在运行executeMethod方法的时候,需要处理两个异常,分别是HttpException和IOException。引起第一种异常的原因主要可能是在构造getMethod的时候传入的协议不对,比如不小心将"http"写成"htp",或者服务器端返回的内容不正常等,并且该异常发生是不可恢复的;第二种异常一般是由于网络原因引起的异常,对于这种异常 (IOException),HttpClient会根据你指定的恢复策略自动试着重新执行executeMethod方法。HttpClient的恢复策略可以自定义(通过实现接口HttpMethodRetryHandler来实现)。通过httpClient的方法setParameter设置你实现的恢复策略,本文中使用的是系统提供的默认恢复策略,该策略在碰到第二类异常的时候将自动重试3次。executeMethod返回值是一个整数,表示了执行该方法后服务器返回的状态码,该状态码能表示出该方法执行是否成功、需要认证或者页面发生了跳转(默认状态下GetMethod的实例是自动处理跳转的)等。 //设置成了默认的恢复策略,在发生异常时候将自动重试3次,在这里你也可以设置成自定义的恢复策略
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler());
//执行getMethod
int statusCode = client.executeMethod(getMethod);
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: " + getMethod.getStatusLine());
}



•在返回的状态码正确后,即可取得内容。取得目标地址的内容有三种方法:第一种,getResponseBody,该方法返回的是目标的二进制的byte流;第二种,getResponseBodyAsString,这个方法返回的是String类型,值得注意的是该方法返回的String的编码是根据系统默认的编码方式,所以返回的String值可能编码类型有误,在本文的"字符编码"部分中将对此做详细介绍;第三种,getResponseBodyAsStream,这个方法对于目标地址中有大量数据需要传输是最佳的。在这里我们使用了最简单的getResponseBody方法。 byte[] responseBody = method.getResponseBody();



•释放连接。无论执行方法是否成功,都必须释放连接。 method.releaseConnection();



•处理内容。在这一步中根据你的需要处理内容,在例子中只是简单的将内容打印到控制台。 System.out.println(new String(responseBody));



下面是程序的完整代码,这些代码也可在附件中的test.GetSample中找到。


package test;
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
public class GetSample{
public static void main(String[] args) {
//构造HttpClient的实例
HttpClient httpClient = new HttpClient();
//创建GET方法的实例
GetMethod getMethod = new GetMethod("https://id:8443/keytest/list");
//使用系统提供的默认的恢复策略
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
new DefaultHttpMethodRetryHandler());
try {
//执行getMethod
int statusCode = httpClient.executeMethod(getMethod);
if (statusCode != HttpStatus.SC_OK) {
System.err.println("Method failed: "
+ getMethod.getStatusLine());
}
//读取内容
byte[] responseBody = getMethod.getResponseBody();
//处理内容
System.out.println(new String(responseBody));
} catch (HttpException e) {
//发生致命的异常,可能是协议不对或者返回的内容有问题
System.out.println("Please check your provided http address!");
e.printStackTrace();
} catch (IOException e) {
//发生网络异常
e.printStackTrace();
} finally {
//释放连接
getMethod.releaseConnection();
}
}
}



POST方法

根据RFC2616,对POST的解释如下:POST方法用来向目的服务器发出请求,要求它接受被附在请求后的实体,并把它当作请求队列(Request-Line)中请求URI所指定资源的附加新子项。POST被设计成用统一的方法实现下列功能:

•对现有资源的注释(Annotation of existing resources)
•向电子公告栏、新闻组,邮件列表或类似讨论组发送消息
•提交数据块,如将表单的结果提交给数据处理过程
•通过附加操作来扩展数据库
调用HttpClient中的PostMethod与GetMethod类似,除了设置PostMethod的实例与GetMethod有些不同之外,剩下的步骤都差不多。在下面的例子中,省去了与GetMethod相同的步骤,只说明与上面不同的地方,并以登录清华大学BBS为例子进行说明。

•构造PostMethod之前的步骤都相同,与GetMethod一样,构造PostMethod也需要一个URI参数,在本例中,登录的地址是http://www.newsmth.net/bbslogin2.php。在创建了PostMethod的实例之后,需要给method实例填充表单的值,在BBS的登录表单中需要有两个域,第一个是用户名(域名叫id),第二个是密码(域名叫passwd)。表单中的域用类NameValuePair来表示,该类的构造函数第一个参数是域名,第二参数是该域的值;将表单所有的值设置到PostMethod中用方法setRequestBody。另外由于BBS登录成功后会转向另外一个页面,但是HttpClient对于要求接受后继服务的请求,比如POST和PUT,不支持自动转发,因此需要自己对页面转向做处理。具体的页面转向处理请参见下面的"自动转向"部分。代码如下: String url = "https://id:8443/keytest/add";
PostMethod postMethod = new PostMethod(url);
// 填入各个表单域的值
NameValuePair[] data = { new NameValuePair("id", "youUserName"),
new NameValuePair("passwd", "yourPwd") };
// 将表单的值放入postMethod中
postMethod.setRequestBody(data);
// 执行postMethod
int statusCode = httpClient.executeMethod(postMethod);
// HttpClient对于要求接受后继服务的请求,象POST和PUT等不能自动处理转发
// 301或者302
if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY ||
statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
// 从头中取出转向的地址
Header locationHeader = postMethod.getResponseHeader("location");
String location = null;
if (locationHeader != null) {
location = locationHeader.getValue();
System.out.println("The page was redirected to:" + location);
} else {
System.err.println("Location field value is null.");
}
return;
}


如有什么疑问大家可以联系我邮箱(meiyx89@163.com)
谢谢来次浏览的牛人,望大家有什么不错技术或想法能拿出来分享!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值