⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssl_with_signature.java

📁 身份认证和数字签名在实际应用中是通过以数字证书为核心的公开密钥基础结构(PKI)来实现的
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
     		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 + -