signcert.java

来自「用纯java语言实现的数字证书制作工具。」· Java 代码 · 共 218 行

JAVA
218
字号
package data;

import java.security.*;
import java.security.spec.*;
import java.security.interfaces.*;
import java.security.cert.*;
import java.io.*;
import data.MyWindowListener;
import java.sql.*;
import data.Connect;
import sun.security.x509.*;
import java.util.*;
import data.GetKey;
import data.BASE64Encoder;
import data.Base64;
import java.math.BigInteger;

//用CA的私钥签发用户提交的待签发证书
//将数字证书存入数据库,同时返回用户一个.cer文件
//前提:有CA根证书rootCA.cer和用户自签发的证书User.cer
//生成CA签发的,受信任的User_formal.cer
public class SignCert
{
	java.security.cert.Certificate ca_cert,user_cert;
	RSAPrivateKey prkey;
	RSAPublicKey userpbkey;
	CertificateFactory cf;
	X509CertInfo userinfo;
	String msg,s_prk;
	java.util.Date begindate,enddate;//validity time
	CertificateSerialNumber csn;//serial number
	X500Name issuer;
	AlgorithmId algorithm;//签名算法
	X509CertImpl new_cert;
	Base64 DE=new Base64();
	BASE64Encoder BE=new BASE64Encoder();
	Connect conn;
	Statement stmt;
	String query;
	
	public SignCert() throws Exception
	{
		//获得ca的证书
		cf=CertificateFactory.getInstance("X.509");
		FileInputStream in=new FileInputStream("rootCA.cer");
		ca_cert=cf.generateCertificate(in);
		in.close();
		
	//	String s_cer=ca_cert.toString();
	//	System.out.println(s_cer);
		
		
		//读取CA私钥
		try{
				
			conn=new Connect();
			stmt=conn.con.createStatement();
			query="select * from ConfigData where ConfigId=1";
			ResultSet rs=stmt.executeQuery(query);	
			int result=0;
			while(rs.next())
			{
				result++;
				try{
				s_prk=rs.getString(4);
				byte[] b_prk =DE.decode(s_prk.getBytes());
				System.out.println(b_prk.toString());
			
     			FileOutputStream f_prk = new FileOutputStream("CAtemp_prk.dat");
     			f_prk.write(b_prk);
     			f_prk.close();
     			
     			}catch(IOException i){
     				System.out.println("临时文件创建错误!");
     			}
				
			}
			if(result==0)/*****测试临时文件读入,跳过数据库,==->!=******/
			{
				System.out.println("还没有密钥对进行签名,请先生成自己密钥对!");
				return;
			}
			else {
				
				try{

     			ObjectInputStream o_prkey=
     				new ObjectInputStream(new FileInputStream("CAtemp_prk.dat"));
     			try{prkey=(RSAPrivateKey)o_prkey.readObject();
     				o_prkey.close();
     				System.out.println(prkey+"\n");
     				}catch(ClassNotFoundException c2){
     					System.out.println("ClassNotFoundException!");
     			}
				}catch(Exception c5){
     					System.out.println("读取临时文件里面的CA私钥错误!");
     			}	
	
     			}
     		}catch(Exception o){
     					msg="CA私钥读取错误!";
					
						System.out.println(msg);
				}
				
		//从CA证书中提取签发者的信息
		
		byte[] encod1=ca_cert.getEncoded();
		X509CertImpl xc=new X509CertImpl(encod1);
		X509CertInfo xcinfo=(X509CertInfo)xc.get(X509CertImpl.NAME+"."+X509CertImpl.INFO);
		issuer=(X500Name)xcinfo.get(X509CertInfo.SUBJECT+"."+CertificateIssuerName.DN_NAME);
		
		
		//待签发证书获取信息
		
			cf=CertificateFactory.getInstance("X.509");
			user_cert=cf.generateCertificate(new FileInputStream("User.cer"));
			byte[] encod2=user_cert.getEncoded();
			X509CertImpl cimp2=new X509CertImpl(encod2);
			userinfo=(X509CertInfo)cimp2.get(
				X509CertImpl.NAME+"."+X509CertImpl.INFO);

		
		//设置版本号 只有v1 ,v2,v3这几个合法值 
		CertificateVersion cv0 = new CertificateVersion(CertificateVersion.V1);
		userinfo.set(X509CertInfo.VERSION,cv0);
		
		//设置证书的有效期3000days
	
		begindate=new java.util.Date(); 
		enddate=new java.util.Date(begindate.getTime()+3000*24*60*60*1000L);
		CertificateValidity	cv=new CertificateValidity(begindate,enddate);
		userinfo.set(X509CertInfo.VALIDITY,cv);
		
		//设置新证书序列号
	
		int sn=(int)(begindate.getTime()/1000);
		csn=new CertificateSerialNumber(sn);
		userinfo.set(X509CertInfo.SERIAL_NUMBER,csn);
		
				
		//设置新证书的签发者
	
		userinfo.set(X509CertInfo.ISSUER+"."+CertificateIssuerName.DN_NAME,issuer);
		
		//设置新证书的签名算法信息
	
		algorithm=new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
		userinfo.set(CertificateAlgorithmId.NAME+"."+CertificateAlgorithmId.ALGORITHM,algorithm);
				
		//创建证书并用CA公钥对其签名
	
		new_cert=new X509CertImpl(userinfo);
		new_cert.sign(prkey,"MD5WithRSA");
		
		//保存证书到文件
		byte[] bc=new_cert.getEncoded();
		FileOutputStream f=new FileOutputStream("User_formal.cer");
		f.write(bc);
		f.close();

		//存储证书到数据库
		 BigInteger SN=new_cert.getSerialNumber();
		 String sigalg=new_cert.getSigAlgName();
		 String DN=new_cert.getSubjectDN().toString();
		 System.out.println(DN);
		 String userpbk=new_cert.getPublicKey().toString();
		 System.out.println(userpbk);
		 byte[] sig=new_cert.getSignature();
		 String Sig=BE.encode(sig);
		 int i=0;
		 char id[]=DN.toCharArray();
		 for(;i<DN.length();i++)
		 {
		 	if(id[i]=='S'&&id[i+1]=='T'&&id[i+2]=='=')
		 		break;
		 }
	
		 char des[]=null;
		 int count=1;
		 i+=3;
		
		 String ID=new String(id,i,8);
	     System.out.println(ID);
		 String CertEnc=BE.encode(bc);
		
		
		try{
			conn=new Connect();
			stmt=conn.con.createStatement();
		query="insert into CertData(Version,SerialNumber,SignatureAlgorithm,Issuers,"
				+"SubjectName,Algorithm,SubjectPublicKey,SignatureValue,UserID,"
				+"UserCertificate) values ('V1','"+SN.toString()+"','"+sigalg+"','"
				+issuer.toString()+"','"+DN+"','RSA','"+userpbk+"','"+Sig+
				"','"+ID+"','"+CertEnc+"')";
		stmt.executeUpdate(query);	
		stmt.close();
		System.out.println("证书存入数据库成功!!!");
		}catch(SQLException sqle){
				String mm;
	       		mm="数据库执行错误:"+sqle.getMessage();
	     	  	System.out.println(mm);
				System.out.println("证书存入数据库错误!!!!");
		}


			
		}	

	public static void main(String args[]) throws Exception
	{
		
		SignCert one=new SignCert();
	}

}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?