安全性要求高的报文,怎样对报文加密?
是使用私钥里进行加密报文,使用公钥解密报文。
public class MsgRealTimeTransDemo {
/**
* 为简洁起见,配置信息作为静态变量,如有调整,可进行修改
*/
private static final String HTTPSPROTOCOL="https"; //协议HTTPS
private static final String ENCODING="gbk";//字符集GBK
private static final String PINGANURL="服务端的服务地址 bis
private static final Integer PINGANPORT=8007;//平安的服务端口 bis
private static final String KEYSTOREPATH="./config/EXV_GROUP_BIS_IFRONT__100.pfx";//密钥文件
private static final String KEYSTOREPASSWORD="paic1234";//密钥文件密码
private static final String TRUSTSTOREPATH="./config/EXV_GROUP_BIS_IFRONT__100.pfx";//授信文件
private static final String TRUSTSTOREPASSWORD="paic1234";//授信文件密码
private static final String PRODUCTCODE="02325";//出单产品代码
/**
* @author HXS
* @date 2012-12-19
* @todo TODO
* @param args
*/
public static void main(String[] args) {
String msgFileName="./config/likebaobaowen.xml";//交易主体报文文件
String message=getMessage(msgFileName);//获取发送交易报文
System.out.println("发送到服务端的请求报文内容:");
System.out.println(message);
String responseStr=sendMsgToPingAn(message); //发送报文到平安
System.out.println("收到服务端的回复报文内容:");
System.out.println(responseStr);
}
/**
* 发送请求报文到服务端并接收服务端的返回结果
* @author HXS
* @date 2012-12-19
* @todo TODO
* @param requestMsg
* @return 返回结果
*/
private static String sendMsgToPingAn(String requestMsg)
{
String responseStr="";
FileInputStream keystoreInstream=null;
FileInputStream trustStoreInstream =null;
try {
keystoreInstream = new FileInputStream(new File(KEYSTOREPATH)); //加载密钥库文件
trustStoreInstream = new FileInputStream(new File(TRUSTSTOREPATH));//加载授信库文件
String keystoreType="";
if(KEYSTOREPATH.toUpperCase().indexOf("PFX")>=0)//判断证书文件的格式
{
keystoreType="PKCS12";
}
else
{
keystoreType="JKS";
}
KeyStore ks = KeyStore.getInstance(keystoreType);
ks.load(keystoreInstream, KEYSTOREPASSWORD.toCharArray());
KeyStore ts = KeyStore.getInstance(keystoreType);
ts.load(trustStoreInstream, TRUSTSTOREPASSWORD.toCharArray());
SSLSocketFactory socketFactory = new SSLSocketFactory(SSLSocketFactory.SSL, ks, KEYSTOREPASSWORD,
ts, null, new TrustStrategy() {
public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
return true;
}
}, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpClient httpclient = new DefaultHttpClient();
Scheme sch = new Scheme(HTTPSPROTOCOL, PINGANPORT.intValue(), socketFactory);//指定协议、URL等信息
httpclient.getConnectionManager().getSchemeRegistry().register(sch);
HttpPost httpPost = new HttpPost(PINGANURL);
StringEntity entity = new StringEntity(requestMsg, "text/html", ENCODING);//指定请求头
httpPost.setEntity(entity);
System.out.println("开始发送数据...");
HttpResponse httpResponse = httpclient.execute(httpPost);//发送请求
System.out.println("接收返回结果...");
HttpEntity resEntity = httpResponse.getEntity();
if (resEntity != null) {
responseStr=EntityUtils.toString(resEntity);//获取结果
}
httpclient.getConnectionManager().shutdown();//关闭连接
} catch (FileNotFoundException e) {
e.printStackTrace();
}catch(Exception e)
{
e.printStackTrace();
}
finally{
if(keystoreInstream!=null)
try {
keystoreInstream.close();
} catch (IOException e) {
e.printStackTrace();
}
if(trustStoreInstream!=null)
try {
trustStoreInstream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return responseStr;
}
/**
* 获取需要发送的报文内容,报文主体结构放置在msgFilePath,其中的某些值需要动态变化
* @author HXS
* @date 2012-12-19
* @todo TODO
* @param msgFilePath 报文主体文件路径
* @return
*/
private static String getMessage(String msgFilePath)
{
String message="";
InputStream is=null;
try {
is = new FileInputStream(new File(msgFilePath));
BufferedReader br=new BufferedReader(new InputStreamReader(is));//加载报文文件
StringBuffer strBuf=new StringBuffer();
String tmp="";
while((tmp=br.readLine())!=null)
{
strBuf.append(tmp).append("\n");
}
Calendar calendar=Calendar.getInstance();
SimpleDateFormat acctDateFormat=new SimpleDateFormat("yyyyMMdd");
SimpleDateFormat acctTimeFormat=new SimpleDateFormat("HH:mm:ss");
SimpleDateFormat insTimeFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
long serial=calendar.getTimeInMillis();
String BK_ACCT_DATE=acctDateFormat.format(calendar.getTime());//交易日期
String BK_ACCT_TIME=acctTimeFormat.format(calendar.getTime());//交易时间
String BK_SERIAL=(new Long(serial)).toString();//交易流水号,每笔交易都不一样
String insuranceBeginTime=insTimeFormat.format(calendar.getTime());//保险起期
String partnerSystemSeriesNo=BK_SERIAL+(int)10*Math.random();//业务流水号。实际业务中,这个字段不能随机生成,而是与业务流水号一致
calendar.add(Calendar.DAY_OF_MONTH, 7);
String insuranceEndTime=insTimeFormat.format(calendar.getTime());//保险止期
String productCode=PRODUCTCODE;//产品代码
//以下是对报文中指定此段插入值
insertValue(strBuf,"<BK_ACCT_DATE>",BK_ACCT_DATE);
insertValue(strBuf,"<BK_ACCT_TIME>",BK_ACCT_TIME);
insertValue(strBuf,"<BK_SERIAL>",BK_SERIAL);
insertValue(strBuf,"<insuranceBeginTime>",insuranceBeginTime);
insertValue(strBuf,"<insuranceEndTime>",insuranceEndTime);
insertValue(strBuf,"<partnerSystemSeriesNo>",partnerSystemSeriesNo);
insertValue(strBuf,"<productCode>",productCode);
message=strBuf.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
if(is!=null)
{
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return message;
}
/**
* 向StringBuffer中插入指定字段的值
* @author HXS
* @date 2012-12-19
* @todo TODO
* @param message 需要插入到的目的字符串
* @param keyName 需要查找的字段名
* @param keyValue 需要插入的字段值
*/
private static void insertValue(StringBuffer message,String keyName,String keyValue)
{
int beginIndex=message.indexOf(keyName)+keyName.length();
message.insert(beginIndex, keyValue);
}
}