本节将较为详细地介绍系统的实现过程主要包括:类的实现(数据库操作类,实体类,事务逻辑处理类),用户界面层。
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