📄 ssl_with_signature.java
字号:
public String Put_Attach_Data(Signature_request S_request)
{
return ""; //不粘贴附加信息
}
/*
* DoneSignature:执行了数字签名后的处理
* sslsignature_record保存本次签名的全部信息
* 把签名记录保存在文件中
*/
public void DoneSignature(SSLsignature_record sslsignature_record)
{
sslsignature_record.save_to_file();
System.err.print("=>"); //显示提示符
return;
}
/**
* 捕捉到签名过程中出错
* Desc:提示信息
* e :例外情况
**/
public void CatchError(String Desc,Exception e){
System.err.println("捕捉到签名请求线程出错。");
System.err.println(Desc + ":" + e.getMessage());
e.printStackTrace();
SSLSignature_Log.Save_Message_Log("Signature.err","时间:"+(new Date()).toString()+"捕捉到签名请求线程出错。\n"+ Desc + ":" + e.getMessage());
System.err.print("=>"); //显示提示符
return;
}
};
do
{
Command=keyinString("=>").toLowerCase(); //命令对大小写不敏感
if(Command.equals("help")){
System.out.println("命令列表");
System.out.println("exit:退出");
System.out.println("accept:开始接受签名请求");
System.out.println("request:发送签名请求");
System.out.println("stop:停止签名请求");
System.out.println("show mycertificate:显示个人证书信息");
System.out.println("show ssl:显示ssl的信息");
System.out.println("httpsslserver:SSL HTTP服务器演示");
System.out.println("https:SSL HTTP客户端演示");
}
if(Command.equals("accept")){
ssl_with_signature.begin_accept_signature_request(callback); //开始监听签名请求
}
if(Command.equals("request")){ //发送签名请求
//String Signdata_desc=keyinString("Signdata_desc:");
String Signdata_desc="您在网上玫瑰超市购物1000元,请您确认该笔金额的支付";
//String Signdata_desc="You have bought the 1000 yuan worth goods in Rose Supermarket,will you confirm this payment?";
//String Signdata=keyinString("Signdata:");
String Signdata="<merchant>Rose Supermarket</merchant><amount>1000.00</amount>";
//String remote_host="localhost";
String remote_host=keyinString("签名响应方的主机:");
ssl_with_signature.request_partner_signature(remote_host,Signdata_desc,Signdata.getBytes());
}
if(Command.equals("show mycertificate")){ //显示个人证书信息
ssl_with_signature.Show_My_Certificate();
}
if(Command.equals("show ssl")){ //显示ssl的信息
ssl_with_signature.Show_SSL_information();
}
if(Command.equals("httpsslserver")){ //SSL HTTP服务器演示
String docroot = keyinString("请输入HTTP服务器的主页目录:");
ServerSocket https_serversocket = ssl_with_signature.listen(443); //443是https的缺省监听端口
if (https_serversocket == null){
Show_Message("创建SSL HTTP服务器失败");
}
else
{
Show_Message("启动SSL HTTP服务器.....");
new ClassFileServer(https_serversocket,docroot,ssl_with_signature);
boolean NeedClientAuth = true;
do
{
if (NeedClientAuth){
System.err.println("现在需要客户端认证,键入noclientauth可以取消客户端认证.");
}
else
{
System.err.println("现在不需要客户端认证,键入needclientauth可以要求客户端认证.");
}
Command=keyinString("键入stop停止:").toLowerCase(); //命令对大小写不敏感
if(Command.equals("noclientauth")){ //不需要客户端认证
NeedClientAuth = false;
((SSLServerSocket)https_serversocket).setNeedClientAuth(NeedClientAuth);
}
if(Command.equals("needclientauth")){ //需要客户端认证
NeedClientAuth = true;
((SSLServerSocket)https_serversocket).setNeedClientAuth(NeedClientAuth);
}
}
while( Command.equals("stop") == false );
https_serversocket.close();
Show_Message("停止SSL HTTP服务器.");
}
}
if(Command.equals("https")){ //SSL HTTP服务器演示
String remote_host = SSL_with_signature.keyinString("主机:");
Socket socket = ssl_with_signature.connect(remote_host,443);
if (socket == null){
SSL_with_signature.Show_Message("联接主机"+remote_host+"出错!");
}
else
{
SSL_with_signature.Show_Message("SSL连接信息:\n" + getSSLsessionMessage(socket));
String uri = SSL_with_signature. keyinString("URI:");
if (uri.startsWith("/") == false)uri ="/" + uri;
String httpstr = "GET "+uri+" HTTP/1.0\r\n\r\n";
SSL_with_signature.Show_Message("发送:"+httpstr);
if ( SSL_with_signature.send(socket,httpstr.getBytes(),httpstr.length()) >0 ){
SSL_with_signature.Show_Message("-----------------接收开始-----------------");
byte buffer[] = new byte[1024];
int recv_length = 0;
int total_length = 0;
while((recv_length = SSL_with_signature.recv(socket,buffer))>0){
SSL_with_signature.Show_Message(new String(buffer));
total_length += recv_length;
}
SSL_with_signature.Show_Message("-----------------接收结束-(共"+Integer.toString(total_length)+"字节)----------------");
}
socket.close();
}
}
if(Command.equals("quit"))Command="exit";
}
while (Command.equals("exit")==false); //键入exit退出
ssl_with_signature.stop_accept_signature_request();
System.exit(0);
}
}
/*****************************************************************************
* SSL_with_signature类的私有类,这个类的对象用独立的线程实现对签名请求的并发监听,
* SSLsignature_reply 对象是SSL_with_signature的私有对象成员,
* 该对象在SSL_with_signature的begin_accept_signature_request方法中创建,这个类不能被公共使用。
* 当SSLsignature_reply接收到签名请求消息时,以弹出窗口的形式提醒用户确认数字签名。
* 本对象是SSL_with_signature附加的私有对象,不能被公共使用
* 使用本对象通过调用SSL_with_signature对象的begin_accept_signature_request函数
* 这样做的目的是为了保护用户私钥
******************************************************************************/
class SSLsignature_reply implements Runnable {
private ServerSocket server = null;
private PrivateKey my_privatekey=null; //自己的私钥,用于签名,不能公开
//public boolean debug_mode = false; //调试模式
private boolean call_stop =false; //调用stop_to_listen
private SSLsignature_reply_callback callback;
private SSLSignature_Log Log_Object;
//private String my_SubjectDN = null; //我的名字,取自我的数字证书
private SSL_with_signature creator = null; //创建这个SSLsignature_reply对象的SSL_with_signature对象
/**
* 构造函数
* ss为接收签名请求的socket
* mykey 为我的私钥,通过参数传递是因为在SSL_with_signature中 my_privatekey不能公开
* who_create_this 为创建这个对象的SSL_with_signature对象
**/
public SSLsignature_reply(ServerSocket ss,PrivateKey mykey,SSL_with_signature who_create_this,SSLsignature_reply_callback reply_callback) throws IOException
{
my_privatekey = mykey;
creator = who_create_this;
if(reply_callback == null){
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:加上签名返回时的附加数据
*/
public String Put_Attach_Data(Signature_request S_request)
{
return ""; //不粘贴附加信息
}
/*
* DoneSignature:执行了数字签名后的处理
* sslsignature_record保存本次签名的全部信息
* 把签名记录保存在文件中
*/
public void DoneSignature(SSLsignature_record sslsignature_record)
{
sslsignature_record.save_to_file();
return;
}
/**
* 捕捉到签名过程中出错
* Desc:提示信息
* e :例外情况
**/
public void CatchError(String Desc,Exception e){
System.err.println("捕捉到签名请求线程出错。");
System.err.println(Desc + ":" + e.getMessage());
e.printStackTrace();
SSLSignature_Log.Save_Message_Log("signature.err","时间:"+(new Date()).toString()+"捕捉到签名请求线程出错。\n"+ Desc + ":" + e.getMessage());
return;
}
};
}
else
callback=reply_callback;
begin_to_listen(ss);
}
/**
* 开始监听连接
**/
public void begin_to_listen(ServerSocket ss)
{
//ss是监听签名请求的服务器Socket
server=ss;
newListener();
Show_Message("开始接收签名请求....");
}
/**
* 停止监听连接
**/
public void stop_to_listen()
{
Show_Debug_Message("停止监听签名请求。");
try{
call_stop=true;
server.close(); //关闭监听的Socket
server=null;
} catch (IOException e)
{
System.err.println("关闭监听的Socket出错: " + e.getMessage());
e.printStackTrace();
return;
}
}
/**
* 检测是否在监听
**/
public boolean listening()
{
return server!=null;
}
/**
* 设置日志对象
**/
public void set_Log(SSLSignature_Log Log)
{
Log_Object=Log;
}
/**
* 生成新的线程
**/
private void newListener()
{
(new Thread(this)).start();
}
/**
* 用线程处理签名请求
**/
public void run()
{
Socket socket;
PublicKey partner_publickey =null; //对方的公钥
// accept a connection
try {
socket = server.accept();
Show_Message("接收到从"+socket.getInetAddress()+"发来的签名请求:");
} catch (IOException e) {
if(call_stop){
Show_Message("接到停止监听签名请求通知。");
call_stop=false;
}
else
{
callback.CatchError("接收签名请求出错",e);
}
return;
}
// create a new thread to accept the next connection
newListener();
//获取对方的证书和公钥
String remote_host=null;
String partner_SubjectDN=null; //对方证书的主题标识名称(subject distinguished name)
javax.security.cert.Certificate partner_cert =null; //对方的证书,要使用Jsse定义的,不能使用原Java定义
try{
//直接从SSL中获取公钥
SSLSession sslsession=((SSLSocket)socket).getSession(); //获取本次SSL连接使用的SSL会话
remote_host=sslsession.getPeerHost(); //获取对方的主机名
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();
} catch (IOException e) {
callback.CatchError("获取对方公钥时出错",e);
return;
}
Signature_reply S_reply=new Signature_reply(); //自己的签名回应
Signature_request S_request=new Signature_request(); //对方的签名请求
//接收签名请求
byte[] buffer=new byte[65536]; //定义通信缓冲区
int recv_len=SSL_with_signature.recv(socket,buffer);
Log_Object.Save_buffer_log("接到"+remote_host+"发来Signature_request包!(len="+Integer.toString(recv_len)+")",buffer,recv_len);
SSL_with_signature.Show_Buffer_Hex("接到"+remote_host+"发来Signature_request包!(len="+Integer.toString(recv_len)+")",buffer,recv_len);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -