PKI数字证书的简单实现

本节将较为详细地介绍系统的实现过程主要包括:类的实现(数据库操作类,实体类,事务逻辑处理类),用户界面层。
2.5.1 类的实现
系统选择jsp+javabean 作为主要的开发方法,结构采用了B/S模式。在这种结构下,用户界面完全通过WWW浏览实现,一部分事务逻辑在前端实现,但主要的事务逻辑是在服务器端实现,形成所谓的3-TIER结构。服务器端的事务逻辑封装在BEAN中,因此JAVABEAN的设计将成为代码实现的核心。
我将从三个方面来介绍:数据库操作类,实体类,事务逻辑处理类(主要是证书的操作)以下着重讲了一些比较典型,在系统中起这比较大的作用的部分。其他的部分有的比较类似。
一、数据库操作类
package com.pki.util;
import java.sql.*;
//连接数据库的工具类。
public class DataBaseConnection
{      /**
        *一个静态方法,返回一个数据库的连接。
        *这样达到了对数据库连接统一控制的目的。
        */
       public static Connection getConnection()
       {     Connection con=null;
           String CLASSFORNAME="com.microsoft.jdbc.sqlserver.SQLServerDriver";
           String SERVANDDB="jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=pkidev";
           String USER="bn";
           String PWD="bn";
           try
           {          Class.forName(CLASSFORNAME);
                     con = DriverManager.getConnection(SERVANDDB,USER,PWD);
              }
              catch(Exception e)
              { e.printStackTrace();}
              return con;
        }
//处理中文
     public String trans(String chi)
      {        String result = null;
               byte temp [];
               try
               { temp=chi.getBytes("iso-8859-1");
                  result = new String(temp);
                }
                catch(java.io.UnsupportedEncodingException e)
                { System.out.println (e.toString());}
           return result;
       }
       public String trans(Object chi)
       { return trans(chi.toString());}
   }
二、实体类
    由于类比较多,也大都相似,我将挑选几个典型的来表示。
CerUserInfor类

package com.pki.CerBean;
import java.util.Date;
import com.pki.util.*;
import java.sql.*;
import java.util.*;
import java.lang.*;
import java.io.*;
public class CerUserInfor
{//属性
   private String comName;
   private String orgnization;
   private String orgUnit;
   private String locality;
   private String state;
   private String country;
   private String email;
   private String netAddr;
   private String cardId;
   private String phone;
   //连接数据库
   private Connection con;
      //getter方法
   public String getComName()
   {return this.comName;}
     
   public String getOrgnization()
   {return this.orgnization;}
             
   public String getOrgUnit()
   {return this.orgUnit;}
            
   public String getLocality()
   {return this.locality;}
  
   public String getState()
   {return this.state;}
  
   public String getCountry()
   {return this.country;}
  
   public String getEmail()
   {return this.email;}
 
   public String getNetAddr()
   {return this.netAddr;}
    
   public String getCardId()
   {return this.cardId;}
 
   public String getPhone()
   {return this.phone;}
    //setter方法
   public void setComName( String c )
   {this.comName = c; }
       
   public void setOrgnization( String c)
   {this.orgnization = c;}
 
   public void setOrgUnit(String c)
   {this.orgUnit = c;}
 
   public void setLocality( String c)
   {this.locality=c;}
 
   public void setState(String c)
   {this.state=c; }
 
   public void setCountry(String c)
   {this.country=c;}
   
   public void setEmail(String c)
   {this.email=c;}
 
   public void setNetAddr(String c)
   {this.netAddr=c;}
 
   public void setCardId(String c)
   {this.cardId=c; }
  
   public void setPhone(String c)
   {this.phone=c;}

    //构造函数
      public CerUserInfor()
       {
        this.con=DataBaseConnection.getConnection(); 
       }//end CerUserInfor()
       //进行CerUserInfor注册
       public void register(CerUserInfor cerUserInfor)throws Exception
       {
              String reg="insert into CerUserInfor"
              + "(CardId,ComName,Orgnization, OrgUnit,Locality,"
              +"State,Country,Email,NetAddr,Phone) "
              +"values(?,?,?,?,?,?,?,?,?,?)";
              try
              {  
                     PreparedStatement pstmt=con.prepareStatement(reg);
                     pstmt.setString(1,cerUserInfor.getCardId());//主关键字
                     pstmt.setString(2,cerUserInfor.getComName());
                     pstmt.setString(3,cerUserInfor.getOrgnization());
                     pstmt.setString(4,cerUserInfor.getOrgUnit());
                     pstmt.setString(5,cerUserInfor.getLocality());
                     pstmt.setString(6,cerUserInfor.getState());
                     pstmt.setString(7,cerUserInfor.getCountry());
                     pstmt.setString(8,cerUserInfor.getEmail());
                     pstmt.setString(9,cerUserInfor.getNetAddr());
                     pstmt.setString(10,cerUserInfor.getPhone());
                     pstmt.executeUpdate();
              }
              catch(Exception e)
              {     e.printStackTrace();
                     throw e;
              }           
       }//end register()
                    
       //进行CerUserInfor更新
       public void update(CerUserInfor cerUserInfor)throws Exception
       {
              String reg="update CerUserInfor set ComName=?,Orgnization=?, "
              +"OrgUnit=?,Locality=?,State=?,Country=?,Email=?,NetAddr=?,Phone=? where CardId=?";
              try
              {  
                     PreparedStatement pstmt=con.prepareStatement(reg);       
                     pstmt.setString(1,cerUserInfor.getComName());
                     pstmt.setString(2,cerUserInfor.getOrgnization());
                     pstmt.setString(3,cerUserInfor.getOrgUnit());
                     pstmt.setString(4,cerUserInfor.getLocality());
                     pstmt.setString(5,cerUserInfor.getState());
                     pstmt.setString(6,cerUserInfor.getCountry());
                     pstmt.setString(7,cerUserInfor.getEmail());
                     pstmt.setString(8,cerUserInfor.getNetAddr());
                     pstmt.setString(9,cerUserInfor.getPhone());
                     pstmt.setString(10,cerUserInfor.getCardId());//主关键字
                     pstmt.executeUpdate();
              }
              catch(Exception e)
              {     e.printStackTrace();
                     throw e;
              }           
       }//end update()
      
       //按CardId查找
       public ResultSet searchByCardId(String cardId)
       {  
              try{
              Statement stm =con.createStatement();
              ResultSet result= stm.executeQuery("select * from CerUserInfor where CardId='"+ cardId +"'");
              return result;
              }catch(Exception e)
           {}
           return null;
       }//end searchByCardId()
       //查找全部
       public ResultSet search()
       {  
              try{
              Statement stm =con.createStatement();
              ResultSet result= stm.executeQuery("select * from CerUserInfor");
              return result;
              }catch(Exception e)
           {}
           return null;
       }//end search()
             
        //删除指定的cardId    
       public void delete(String cardId)throws Exception
       {
              try
              {
              Statement stmt=con.createStatement();
              stmt.execute("delete from CerUserInfor where CardId='"+ cardId +"'");
              }
              catch(Exception e)
              {   e.printStackTrace();
                     throw e;
              }
       }//end delete()
 
 }//end class
三、事务逻辑处理类
在此仅给出比较核心的CertBean 类。
CertBean 类 :进行产生证书、签名、导出证书、签名验证、有效期验证、条目密码设置、证书删除等操作
       package com.pki.CerBean;
import com.pki.util.*;
import java.sql.*;
import java.io.*;
import java.lang.*;
import java.util.*;
import java.util.Date;
import java.math.*;
import java.security.*;
import java.security.cert.*;
import java.security.cert.Certificate;
import sun.security.x509.*;
public class CertBean{
       //连接数据库
   private Connection con;
   private String keystore;//证书库
   private String storepass;//证书库密码
   private String capass;//根证书密码
   private String caalias;//根证书别名
   private String keypass;//用户证书密码
   private String comName;//用户证书别名
   private int Validity; //证书有效期
       //构造函数
      public CertBean()
       {this.con=DataBaseConnection.getConnection();
        this.keystore="f://cerstore//mykeystore";//证书库
        this.storepass="rootca";
        this.capass="rootca";
        this.caalias="RootCA";
       } //end CertBean()
       //产生证书
       public boolean GenerateCert(ResultSet ret1,ResultSet ret2) throws Exception
       {
          String CN,OU,O,L,ST,C,validity,keysize ;
          try{
            //设置值
           ret1.next();
           ret2.next();
        CN=ret1.getString("ComName");
        this.comName=CN;
           O=ret1.getString("Orgnization");
           OU=ret1.getString("OrgUnit");
           L=ret1.getString("Locality");
           ST=ret1.getString("State");
           C=ret1.getString("Country");
           this.Validity=ret2.getInt("Validity");
           validity=Integer.toString(this.Validity);
           keysize=Integer.toString(ret2.getInt("KeyNo"));
           this.keypass=ret2.getString("StoreKey");
        //生成证书和证书库的命令
           String exeString = "keytool -genkey -dname /"" 
           +"CN=" + CN +",OU="+OU+",O="+O+",L="+L+",ST="+ST+",C="+ C +"/""
           + " -alias "+ CN +" -keyalg RSA -keysize " + keysize + " -keystore " + this.keystore
           + " -storepass " + this.storepass +" -keypass " + this.keypass + " -validity " + validity;
          Runtime.getRuntime().exec(exeString);
          Thread.sleep(2000);
              return true;
              }
              catch(Exception e){}
              return false;
       }//end GenerateCert()
  //证书签名
       public boolean SignCert() throws Exception
       {
   //证书签名----根证书RootCA,待签名证书user都放在同一证书库中-----
        //设置密码值
        try{
        char[] storepass= this.storepass.toCharArray();
        char[] cakeypass= this.capass.toCharArray();
       //对根证书 ca 操作
        FileInputStream in1=new FileInputStream(this.keystore);
        KeyStore ks=KeyStore.getInstance("JKS");
        ks.load(in1,storepass);
        java.security.cert.Certificate ca=ks.getCertificate(this.caalias);
        PrivateKey caprk=(PrivateKey)ks.getKey(this.caalias,cakeypass);
        in1.close();
       //得到证书信息
        byte[] encodca=ca.getEncoded();
        X509CertImpl cimplca=new X509CertImpl(encodca);
        X509CertInfo cinfoca=(X509CertInfo)cimplca.get(X509CertImpl.NAME +
        "." + X509CertImpl.INFO);
        X500Name issuer =(X500Name)cinfoca.get(X509CertInfo.SUBJECT +
        "." + CertificateIssuerName.DN_NAME);
        //对待签名证书 user 操作
        //取待签名证书user的密钥
        char[] userkeypass= this.keypass.toCharArray();
        //待签证书别名---------------------------
        String useralias = this.comName;
        FileInputStream in2=new FileInputStream(this.keystore);
        ks.load(in2,storepass);
        java.security.cert.Certificate user=ks.getCertificate(useralias);
        in2.close();
        //得到证书信息
        byte[] encoduser=user.getEncoded();
        X509CertImpl cimpluser=new X509CertImpl(encoduser);
        X509CertInfo cinfouser=(X509CertInfo)cimpluser.get(X509CertImpl.NAME +
        "." + X509CertImpl.INFO);
        //设置新证书有效期 eg 3000天(毫秒数)---------------
        Date begindate =new Date();
        Date enddate =new Date(begindate.getTime() + this.Validity*24*60*60*1000L);
        CertificateValidity cv = new CertificateValidity(begindate,enddate);
        cinfouser.set(X509CertInfo.VALIDITY,cv);
        //设置新证书序列号
        int sn=(int)(begindate.getTime()/1000);
        CertificateSerialNumber csn= new CertificateSerialNumber(sn);
        cinfouser.set(X509CertInfo.SERIAL_NUMBER, csn);
        //设置新证书签发者
     cinfouser.set(X509CertInfo.ISSUER +
     "." + CertificateIssuerName.DN_NAME,issuer);
     //设置新证书算法
     AlgorithmId algorithm =new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
     cinfouser.set(CertificateAlgorithmId.NAME + 
     "." + CertificateAlgorithmId.ALGORITHM,algorithm);
      //创建证书
     X509CertImpl signcert=new X509CertImpl(cinfouser);
     //签名
     signcert.sign(caprk,"MD5WithRSA");
     System.out.println(signcert);
     //存入密钥库
     ks.setCertificateEntry(this.comName + "_signed",signcert);
     FileOutputStream out=new FileOutputStream(this.keystore);
     ks.store(out,storepass);
     out.close();
     Thread.sleep(2000);
     return true;
    }catch(Exception e){}
    return false;
   }//end SignCert()
        //生成.cer文件
    public String exportCert() throws Exception
       {  
 try{ //生成.cer文件命令
           String exeString= "keytool -export -keystore "+ this.keystore +" -storepass "+ this.storepass
           + " -alias "+ this.comName +"_signed" + " -file f://cerstore//cer_signed//"+ this.comName +"_signed.cer -rfc";     
            Runtime.getRuntime().exec(exeString);
            String url="F://cerstore//cer_signed//"+ this.comName +"_signed.cer";
              return url;
              }
              catch(Exception e){}
              return null;           
       }//end exportCert()
       //证书签名验证 正确返回true ,错误返回 false
       public boolean CheckCertSign(String alias ,String keypass)throws Exception
     { char[] storepass= this.storepass.toCharArray();
        //ca 证书
        FileInputStream in1=new FileInputStream(this.keystore);
        KeyStore ks=KeyStore.getInstance("JKS");
        ks.load(in1,storepass);
        java.security.cert.Certificate ca=ks.getCertificate(this.caalias);
        PublicKey pbk=(PublicKey)ca.getPublicKey();
        in1.close();
        X509Certificate t= (X509Certificate) ca ;
       //对待验证签名证书 user 操作
       char[] userkeypass= keypass.toCharArray();
        FileInputStream in2=new FileInputStream(this.keystore);
        ks.load(in2,storepass);
        java.security.cert.Certificate user=ks.getCertificate(alias);
        in2.close();  
        boolean pass=false;
        try{user.verify(pbk);
            pass=true;
             }catch(Exception e){pass= false;}
             if(pass){ return true ;}  
              else{ return false ;}      
       }//end CheckCertSign()
       //显示所有条目别名
 public Enumeration ShowAllAlias() throws Exception
       {char[] storepass= this.storepass.toCharArray();
        FileInputStream in=new FileInputStream(this.keystore);
        //初始化密钥库工厂
        KeyStore ks=KeyStore.getInstance("JKS");
        ks.load(in,storepass);
        //得到所有的alias
        Enumeration e=ks.aliases();
        return e;
    }//end     ShowAllAlias()
        //证书有效期验证 有效返回 1,未生效返回 0 ,过期返回-1
 public int CheckCertValid(String alias )throws Exception
       { char[] storepass= this.storepass.toCharArray(); 
        FileInputStream in=new FileInputStream(this.keystore);
        //初始化密钥库工厂
        KeyStore ks=KeyStore.getInstance("JKS");
        ks.load(in,storepass);
        Certificate c=ks.getCertificate(alias);
        in.close();
        //转化为X.509证书
        X509Certificate t= (X509Certificate) c ;
        //读取证书
        Calendar cld=Calendar.getInstance();
        Date d=cld.getTime();
        System.out.println(d);
        //检验有效期
        try{t.checkValidity(d);
             return 1;
           }catch(CertificateExpiredException e)
             {return -1 ;}
             catch(CertificateNotYetValidException e)//还未生效
           { return 0 ;}              
   }//end CheckCertValid()
   //设置条目密码
 public void SetKeyPass(String alias ,String old_keypass,String new_keypass ) throws Exception
       {
//设置密钥库中条目的密钥
        char[] oldkeypass = old_keypass.toCharArray();
        char[] newkeypass = new_keypass.toCharArray();    
        char[] storepass= this.storepass.toCharArray();  
        FileInputStream in=new FileInputStream(this.keystore);
        //初始化密钥库工厂
        KeyStore ks=KeyStore.getInstance("JKS");
        ks.load(in,storepass);
        PrivateKey prk=(PrivateKey)ks.getKey(alias,oldkeypass);
     java.security.cert.Certificate[] cchain =ks.getCertificateChain(alias);
     //可以用此来添加条目,只要第一个参数不同,相同时将被覆盖   
        ks.setKeyEntry(alias ,prk,newkeypass ,cchain); 
        in.close();    
        FileOutputStream out=new FileOutputStream(this.keystore);
     ks.store(out,storepass);
     out.close();
   }//end SetKeyPass()
//从密钥库中删除证书条目
 public boolean DeleteCertFromStore(String alias ) throws Exception
       {  try{
//生成删除命令
           String exeString ="keytool -delete -alias "+ alias +" -keystore "
           +this.keystore +" -storepass " + this.capass ;
            Runtime.getRuntime().exec(exeString);
              return true;     }
              catch(Exception e){}
              return false;          
       }//end DeleteCertFromStore()
 }//end class CertBean
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值