(接上篇)
注意:TestSSL类中采用瑞士网的资源来测试,分析参数时,我使用了工具HttpProfessional4.1(网页参数请求头解析工具,行业中使用的东东,请上网查一下如何用,我在此不作详细说明.)作分析.
经分析:瑞士网在设定好https协议后进行获取时会生成一个JESSIONID.此值将设在请求头中.并和初始页面中动态生成的一个隐式参数javax.faces.ViewState,重新组成一个post请求体参数用于再一次的递交请求获取.(TestSSL类主要是设定https,并照分析流程那样进行执行相关提取数据操作,并再次设定请求url获取页面.)
若朋友们对此过程了解.则跳过此类(TestSSL.java),并重点关注后面三个有关https的重要实现类.
相关的所有源码如下:
==========================
TestSSL类
===========================
/
// 测试httpclient之https(ssl)..
///
package edu.bin.study.ssl;
import java.net.URL;
import
org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.protocol.Protocol;
import
org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import
com.ibatis.common.resources.Resources;
/
//TestSSL类
///
public class TestSSL {
/
// 请求地址集
///
private String[] httpUrls = {
"www.swissreg.ch/srclient",
"www.swissreg.ch/srclient/faces/jsp/start.jsp"
};
/
// 存钥集
///
private String[] keystoreUrls = {
"edu/bin/extend/verisign.keystore",
"edu/bin/extend/swissreg.keystore"
};
/
// 信任证书集
///
private String[] truststoreUrls = {
"edu/bin/extend/verisign.truststore",
"edu/bin/extend/swissreg.truststore"
};
/
// password密码
///
private String password = "123456";
/
// 依次为:请求地址,存钥地址,信任钥地址.
///
private String urlString, keystoreUrlString,
truststoreUrlString;
/
// Header请求头
///
private String headerValue;
//post请求体
///
private String[]
requestBodyStrings = {
"id_swissreg_SUBMIT=1&id_swissreg%3A_link_hidden_=&id_swissreg%3A_idcl=id_swissreg%3Asub_language%3AlanguageList%3A3%3A_idJsp4&javax.faces.ViewState=@viewStatus@"
};
/
// main函数程序入口
//
// @param args
///
public static void main(String[] args) {
// TODO
进行相关测试
TestSSL tssl = new
TestSSL();
tssl.StartTest();
}
/
// 进行相关测试
///
private void StartTest() {
try {
//
采用传统的URL构建...
// URL
keystoreUrl = new URL("file://d:/swissreg.keystore");
//
URL("url:edu/bin/extend/swissreg.keystore");
// URL
truststoreUrl = new URL("file://d:/swissreg.truststore");
//
URL("url:edu/bin/extend/swissreg.truststore");
//
采用ibaits框架部份读取构建..
int
index = 1;
urlString =
httpUrls[index];
keystoreUrlString
= keystoreUrls[index];
truststoreUrlString
= truststoreUrls[index];
URL
keystoreUrl = Resources.getResourceURL(keystoreUrlString);
String
keystorePassword = password;
URL
truststoreUrl =
Resources.getResourceURL(truststoreUrlString);
String
truststorePassword = password;
//
进行构建协议..
SecureProtocolSocketFactory
spsfactory = new AuthSSLProtocolSocketFactory(
keystoreUrl,
keystorePassword, truststoreUrl,
truststorePassword);
Protocol
authhttps = new Protocol("https", spsfactory, 443);
HttpClient
httpClient = new HttpClient();
//
设置1(只可与设置2任选一个设定写法.)
Protocol.registerProtocol("https",
authhttps);
HttpMethod
method = new GetMethod("https://" + urlString);
//
//设置2//
httpClient.getHostConfiguration()
//
.setHost(urlStirng, 443, authhttps);
// HttpMethod
method = new GetMethod("/");
httpClient.executeMethod(method);
Header[]
headrs = method.getResponseHeaders();
httpClient.executeMethod(method);
// 提取VIEWSTATE
String
htmlString = method.getResponseBodyAsString();
this.PrintHeader(headrs);
String
viewStatus = htmlString
.split("id="javax.faces.ViewState"
value="")[1];
viewStatus =
viewStatus.split("" />")[0];
String
requestBodyString = requestBodyStrings[0];
requestBodyString
= requestBodyString.replaceAll("@viewStatus@",
viewStatus);
urlString =
httpUrls[1];
urlString+=";"+(headerValue.replaceAll("JSESSIONID",
"jsessionid"));
urlString="https://"+urlString;
System.out.println("合成urlString:"+urlString);
method=new
GetMethod(urlString);
httpClient.executeMethod(method);
PostMethod
postMethod = new PostMethod(urlString);
postMethod.setRequestBody(setNameValuePair(requestBodyString));
method.setRequestHeader("Cookie",
headerValue);
method =
postMethod;
httpClient.executeMethod(method);
htmlString =
method.getResponseBodyAsString();
System.out.println("\n获取页面htmlString:\n" +
htmlString);
if (method
!= null) {
method.releaseConnection();
}
if
(postMethod != null) {
postMethod.releaseConnection();
}
} catch (Exception e) {
// TODO:
handle exception
e.printStackTrace();
}
}
/
// 打印请求头..
//
// @param headers
///
private void PrintHeader(Header[] headers)
{
int count =
headers.length;
String infoString = null;
for (int i = 0; i < count;
i++) {
infoString =
"\n请求头名:" + headers[i].getName() + "\t请求头值:"
+
headers[i].getValue();
System.out.println(infoString);
if
(headers[i].getName().equalsIgnoreCase("Set-Cookie")) {
headerValue
= headers[i].getValue().split(";")[0];
}
}
}
/
//
此方法在于将常见的请求体RequestBodyString转换成标准要求的NameValuePairs
//
// @param requestBodyString
// @return
///
private static NameValuePair[]
setNameValuePair(String requestBodyString) {
String[] nameValueStrings =
requestBodyString.split("&");
int count =
nameValueStrings.length;
NameValuePair[]
nameValuePairs = new NameValuePair[count];
NameValuePair nameValuePair
= null;
String[] temp = null;
int countTemp = 0;
for (int i = 0; i <
count; i++) {
//
注意:nameValuePair只可创建设置一次,不可复用,否则异常!
nameValuePair
= new NameValuePair();
temp =
nameValueStrings[i].split("=");
countTemp =
temp.length;
switch
(countTemp) {
case 1:
nameValuePair.setName(temp[0]);
nameValuePair.setValue("");
break;
case 2:
nameValuePair.setName(temp[0]);
nameValuePair.setValue(temp[1]);
break;
default:
break;
}
nameValuePairs[i]
= nameValuePair;
//
显示键值对
System.out.println(i
+
"\nnameValuePairs(name)\\nameValuePairs(Value):"
+
nameValuePairs[i].getName() + "\"
+
nameValuePairs[i].getValue());
}
return nameValuePairs;
}
}
==============================================
以下是3个极其重要的类
1)用于SSL类重写的初始化.AuthSSLInitialzationError.java(以下全是构造方法多态表现形式)
============================================
package edu.bin.study.ssl;
public class AuthSSLInitialzationError extends Error {
public AuthSSLInitialzationError() {
// TODO
Auto-generated constructor stub
}
public AuthSSLInitialzationError(String message)
{
super(message);
// TODO
Auto-generated constructor stub
}
public AuthSSLInitialzationError(Throwable cause)
{
super(cause);
// TODO
Auto-generated constructor stub
}
public AuthSSLInitialzationError(String message,
Throwable cause) {
super(message, cause);
// TODO
Auto-generated constructor stub
}
}
=========================================
2)信任管理器类AuthSSLX509TrustManager.java
=======================================
///AuthSSLX509TrustManager.java
package edu.bin.study.ssl;
import
java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import
javax.net.ssl.X509TrustManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
// @author bin
//
// @date 2007-12-31
// public class AuthSSLX509TrustManager implements X509TrustManager
{
//
X509信任管理器声明.
private X509TrustManager x509tm;
// Log
private static final Log LOG = LogFactory
.getLog(AuthSSLX509TrustManager.class);
// 构造方法
//
// @param x509tm
public AuthSSLX509TrustManager(final
X509TrustManager x509tm) {
super();
if (x509tm == null) {
throw new
IllegalArgumentException("信任管理器不可为空");
}
this.x509tm = x509tm;
}
//
重写检查客户端信任..
//
// @see
javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[],
// java.lang.String)
public void checkClientTrusted(X509Certificate[]
certificates, String arg1)
throws
CertificateException {
// TODO
日志记录信息.
if (LOG.isInfoEnabled()
&& certificates != null) {
String
temp_info = "\n客户端信任证书{0}:\nSubject DN:{1}\nSignature
Algorithm:{2}\nValid from:{3}\nValid
until:{4}\nIssuer:{5}\n";
String
log_info = "";
X509Certificate
cert = null;
for (int i =
0; i < certificates.length; i++) {
cert
= certificates[i];
log_info
+= String.format(temp_info, i + 1,
cert.getSubjectDN(),
cert.getSigAlgName(), cert
.getNotBefore(),
cert.getNotBefore(), cert
.getIssuerDN());
}
}
// String
arg1我没用上.. }
// 重写服务器端信任.
//
// @see
javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[],
// java.lang.String)
public void checkServerTrusted(X509Certificate[]
certificates, String arg1)
throws
CertificateException {
// TODO
日志记录信息.
if (LOG.isInfoEnabled()
&& certificates != null) {
String
temp_info = "\n服务端信任证书{0}:\nSubject DN:{1}\nSignature
Algorithm:{2}\nValid from:{3}\nValid
until:{4}\nIssuer:{5}\n";
String
log_info = "";
X509Certificate
cert = null;
for (int i =
0; i < certificates.length; i++) {
cert
= certificates[i];
log_info
+= String.format(temp_info, i + 1,
cert.getSubjectDN(),
cert.getSigAlgName(), cert
.getNotBefore(),
cert.getNotBefore(), cert
.getIssuerDN());
}
}
// String
arg1我没用上.. }
//
返回公认发行证书集..
//
// @see
javax.net.ssl.X509TrustManager#getAcceptedIssuers()
public X509Certificate[] getAcceptedIssuers()
{
// TODO
返回公认发行集.
return
this.x509tm.getAcceptedIssuers();
}
}
(中篇完)