📄 ssl_with_signature.java
字号:
}
else
{
replydata_length = buffer[p] & 127 + 128;
}
replydata_length = replydata_length <<8;
p++;
if(buffer[p] >=0 ){
replydata_length = buffer[p];
}
else
{
replydata_length = buffer[p] & 127 + 128;
}
p++;
S_reply.replydata_length = replydata_length;
S_reply.replydata=new byte[S_reply.replydata_length];
for(int i=0;i<S_reply.replydata_length;i++)S_reply.replydata[i]=buffer[p++];
byte signatureAlgorithm=buffer[p++]; //签名算法
//int s_length=(new Byte(buffer[p++])).intValue(); //签名值的长度
int s_length = 0;
if(buffer[p]>=0){
s_length = buffer[p];
}
else
{
s_length = buffer[p] & 127 + 128;
}
p++;
byte[] signatureValue=new byte[s_length];
for(int i=0;i<s_length;i++)signatureValue[i]=buffer[p++];
DSignature reply_signature=new DSignature(signatureAlgorithm,s_length,signatureValue);
S_reply.signature=reply_signature;
Show_Message("对方返回签名响应,内容如下:");
Show_Message(S_reply.toString());
//验证对方的签名
//获取对方的证书和公钥
String partner_SubjectDN=null; //对方证书的主题标识名称(subject distinguished name)
javax.security.cert.Certificate partner_cert =null; //对方的证书,要使用Jsse定义的,不能使用原Java定义
PublicKey partner_publickey = null;
try{
//直接从SSL中获取公钥
SSLSession sslsession=((SSLSocket)s).getSession(); //获取本次SSL连接使用的SSL会话
partner_cert=(javax.security.cert.Certificate)(sslsession.getPeerCertificateChain()[0]); //对方的证书
Show_Debug_Message("对方证书信息");
Show_Debug_Message(partner_cert.toString());
partner_publickey=partner_cert.getPublicKey();
Show_Debug_Message("对方的公钥信息");
Show_Debug_Message(partner_publickey.toString());
partner_SubjectDN=((javax.security.cert.X509Certificate)partner_cert).getSubjectDN().getName();
if(S_reply.signature.Verify(S_reply.replydata,partner_publickey)){
Show_Message("对方的数字签名验证通过!");
}
else
{
Show_Message("对方的数字签名验证无法通过,可能是一个非法的签名!");
}
} catch (Exception e) {
System.err.println("试图验证对方数字签名时出错:" + e.getMessage());
e.printStackTrace();
}
try{
s.close(); //关闭socket
} catch (IOException e)
{
System.err.println("关闭socket出错:" + e.getMessage());
e.printStackTrace();
}
Show_Message("保存签名记录");
Log_Object.SaveSignToLog(partner_SubjectDN+"在"+partner_host+"返回签名响应,\n",S_request,S_reply);
return new SSLsignature_record(S_request,S_reply,my_certificate,partner_cert); //这里即使验证数字签名通不过也不管
}
else
{
Show_Message("对方返回的随机数与我方发出的不同!");
try{
s.close(); //关闭socket
} catch (IOException e)
{
System.err.println("关闭socket出错:" + e.getMessage());
e.printStackTrace();
}
return null;
}
default:
Show_Message("接收到的消息类型不对!");
try{
s.close(); //关闭socket
} catch (IOException e)
{
System.err.println("关闭socket出错:" + e.getMessage());
e.printStackTrace();
}
return null;
}
//return null;
}
/**
* 显示调试信息
**/
public static void Show_Debug_Message(String msg){
if(debug_mode){
System.err.println(msg);
System.err.flush();
}
}
/**
* 显示提示信息
**/
public static void Show_Message(String msg){
System.out.println(msg);
System.out.flush();
}
/**
* Show_Buffer_Hex:以Hex方式显示缓冲区的内容
**/
public static void Show_Buffer_Hex(String Desc,byte[] buf,int len) {
if(debug_mode){
System.err.println(Desc+":");
for(int i=0;i<len;++i){
System.err.print("["+Conversion.byteToHexString(buf[i])+"]");
}
System.err.println();
}
}
/**
* 提示客户输入信息
**/
public static String keyinString(String prompt){
try{
String inputLine;
BufferedReader in=new BufferedReader(
new InputStreamReader(System.in));
//System.err.println();
System.err.print(prompt);
System.err.flush();
inputLine=in.readLine();
return inputLine;
} catch (IOException e) {
System.err.println("输入信息出错:" + e.getMessage());
e.printStackTrace();
return null;
}
}
/**
* 弹出输入窗口提示用户输入字符串
* Desc 为提示
* echoinput 为true时显示键入的字符 为false显示*号
* 返回输入的字符串
**/
public static String inputString_with_window(String Desc,boolean echoinput)
{
return message_box.inputString(Desc,echoinput);
}
/**
* 等价于inputString_with_window(String Desc,true);
**/
public static String inputString_with_window(String Desc)
{
return inputString_with_window(Desc,true);
}
/**
* 要求用户人工确认签名
* S_request:签名请求消息
* partner_cert:对方的数字证书
**/
public static boolean RequestPeopleConfirmSign(Signature_request S_request,javax.security.cert.Certificate partner_cert)
{
Show_Message("以下是您收到的签名请求:");
Show_Message("签名请求者证书:"+partner_cert.toString());
String Desc_Message = null;
try{
Show_Message("请求签名的原因描述:"+(new String(S_request.signdata_desc,SSL_with_signature.BYTE_ENCODING)));
Show_Message("要求您签名的数据:"+(new String(S_request.signdata,SSL_with_signature.BYTE_ENCODING)));
Desc_Message = "收到签名请求\n对方的数字证书:\n"+partner_cert.toString()+
"\n请求签名的原因描述:"+(new String(S_request.signdata_desc,SSL_with_signature.BYTE_ENCODING))+"\n"+
"要求您签名的数据:"+(new String(S_request.signdata,SSL_with_signature.BYTE_ENCODING))+"\n"+
"您同意为该支付请求签名吗,提醒您注意,您的签名将具法律效力\n键入YES后表示同意,其他取消:";
} catch ( UnsupportedEncodingException e)
{
Show_Message("请求签名的原因描述(使用本地字符集):"+(new String(S_request.signdata_desc)));
Show_Message("要求您签名的数据:"+(new String(S_request.signdata)));
Desc_Message = "收到签名请求\n对方的数字证书:\n"+partner_cert.toString()+
"\n请求签名的原因描述:"+(new String(S_request.signdata_desc))+"\n"+
"要求您签名的数据:"+(new String(S_request.signdata))+"\n"+
"您同意为该支付请求签名吗,提醒您注意,您的签名将具法律效力\n键入YES后表示同意,其他取消:";
}
Show_Message("十六进制表示:");
Show_Message(Conversion.byteArrayToHexString(S_request.signdata));
String command=SSL_with_signature.inputString_with_window(Desc_Message);
Show_Message("您选择了"+command);
if(command.toUpperCase().equals("YES"))
{
//SaveSignToLog(partner_name,S_request,S_reply);
return true;
}
else
{
return false;
}
}
/**
* main仅用于调试和演示SSL签名协议
* 程序用法:
* java com.zsusoft.zfl.SSL_with_signature [-debug] <mykeystore:私钥库> [-alias:Key Entry的alias] [-password:密码]
* <-certkeystore:信任证书库> [-certpassword:密码] [-logfile:日志文件名]
* 参数项目不分先后 其中[]表示可选 <>表示必选
* 使用的私钥库和证书库使用SUN JKS(Java Key Store)格式文件
**/
public static void main(String[] args) throws Exception {
boolean debug_mode = false;
String my_keystorefile = null; //我的私钥库
String my_alias = "mykey"; //私钥库中放私钥的项目的alias name(参考Java Key Store的说明)
String password =null; //访问私钥的密码,本处假定访问私钥的密码和存取Java Key Store的密码相同
String trust_keystorefile = null ; //信任证书库
String trust_password = null ; //信任证书库的访问密码
String logfile =null;
for (int i = 0; i < args.length; ++i){
if(args[i].equals("-debug"))debug_mode=true;
if(args[i].startsWith("-mykeystore:")){
my_keystorefile=args[i].substring(12);
//System.out.println("密钥库:"+my_keystorefile);
}
if(args[i].startsWith("-alias:")){
my_alias=args[i].substring(7);
//System.out.println("私钥的alias name:"+my_alias);
}
if(args[i].startsWith("-password:")){
password=args[i].substring(10);
//System.out.println("密钥库密码:"+password);
}
if(args[i].startsWith("-certkeystore:")){
trust_keystorefile=args[i].substring(14);
//System.out.println("证书库:"+trust_keystorefile);
}
if(args[i].startsWith("-certpassword:")){
trust_password=args[i].substring(14);
//System.out.println("证书库密码:"+trust_password);
}
if(args[i].startsWith("-logfile:"))logfile=args[i].substring(9);
}
Show_Message("********************************************************************");
Show_Message("* 软件:Java签名协议扩展 (Java Signature Protocol Extension, JSPE) *");
Show_Message("* 版本:V1.0 *");
Show_Message("* 软件功能:实现SSL签名协议 *");
Show_Message("*------------------------------------------------------------------*");
Show_Message("* 版权所有:中山大学软件研究所 2002 *");
Show_Message("* Programmed by 佛山张峰岭 fszfl@21cn.com *");
Show_Message("* 2002.4 - 2002.5 *");
Show_Message("********************************************************************");
if((my_keystorefile == null)||(trust_keystorefile == null)){
System.err.println("程序用法:");
System.err.println("java com.zsusoft.zfl.SSL_with_signature [-debug] <mykeystore:私钥库> [-alias:Key Entry的alias] [-password:密码] \\");
System.err.println(" <-certkeystore:信任证书库> [-certpassword:密码] [-logfile:日志文件名]");
System.err.println("参数项目不分先后 其中[]表示可选 <>表示必选");
System.exit(-1); //退出
}
if(password == null){
password=inputString_with_window("请输入您的个人私钥库的密码:",false);
}
KeyStore mykeystore = KeyStore.getInstance("JKS", "SUN");;
try{
mykeystore.load(new FileInputStream(my_keystorefile),password.toCharArray());
} catch (Exception e)
{
System.err.println("装入私人密钥库"+ my_keystorefile + "出错:" + e.getMessage());
e.printStackTrace();
System.exit(-1);
}
if(trust_password == null){
trust_password=inputString_with_window("请输入信任证书库的密码:",false);
}
KeyStore trustkeystore = KeyStore.getInstance("JKS", "SUN");
try{
trustkeystore.load(new FileInputStream(trust_keystorefile),trust_password.toCharArray());
} catch (Exception e)
{
System.err.println("装入信任证书库"+ trust_keystorefile +"出错:" + e.getMessage());
e.printStackTrace();
System.exit(-1);
}
String Command="Wait";
SSL_with_signature ssl_with_signature = null;
try{
ssl_with_signature = new SSL_with_signature(mykeystore,my_alias,password,trustkeystore,logfile);
} catch ( Exception e)
{
System.err.println("创建SSL_with_signature对象出错:" + e.getMessage());
e.printStackTrace();
System.exit(-1);
}
ssl_with_signature.debug_mode=debug_mode;//设置调试开关
System.out.println("见=>请输入命令 exit退出,help帮助");
//定义回调函数
SSLsignature_reply_callback callback=new SSLsignature_reply_callback()
{
/*
* Check_Signature_Request:表示接收到合法的签名请求后检查签名请求中的数据
* 可以在这个地方加入执行签名前的一些前期处理,返回false表示拒绝签名
* S_request是签名请求数据
* partner_cert是从SSLsession中获取的对方的证书
*/
public boolean Check_Signature_Request(Signature_request S_request,javax.security.cert.Certificate partner_cert){
return SSL_with_signature.RequestPeopleConfirmSign(S_request,partner_cert); //用户人工确认
}
/*
* Put_Attach_Data:加上签名返回时的附加数据
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -