基于PKI的课程设计选题系统相关笔记(二)
这一次主要记录一下PKI证书是如何生成的,以及如何从证书库中导出证书
1.使用keytool生成根CA自签名证书
#KeyTool是JDK自带的一个证书相关的工具
#-genkey 产生证书
#-alias 证书别名
#-keyStore 证书库路径
#-ketalg 密钥算法
#-keysize 密钥长度
#-validity 证书有效期
keytool -genkey -alias root -keyStore identity.jks -Keyalg RSA -keysize 1024 -validity 3650
2.为注册用户生成根CA签名的证书
/*
*先指定根CA的X500Name
*X500Name:X.500 names are used to identify entities,
* such as those which are identified by X.509 certificates.
*然后从密钥库中取得根CA的私钥,用于对证书签名
*/
X500Name x500Name = new X500Name("CN=root, OU=UESTC, O=UESTC, L=Chengdu, ST=Sichuan, C=CN");
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream in = new FileInputStream("E:/workspace/CurriculumDesign/src/main/resources/identity.jks");
String storePass = "123456";
ks.load(in, storePass.toCharArray());
PrivateKey pk = (PrivateKey) ks.getKey("root", storePass.toCharArray());
in.close();
接下去为用户生成证书,并签名
/*
*先为用户生成公私钥对:username为用户名
*然后指定X509证书中的相关信息,包括:
* 1.证书版本号
* 2.证书序列号
* 3.证书签名算法
* 4.证书使用者
* 5.证书使用者公钥
* 6.证书有效期
* 7.证书颁发者
* 8.证书签名
*将证书存入到证书库中
*/
KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");
kg.initialize(1024, new SecureRandom());
KeyPair keyPair = kg.generateKeyPair();
String name = "CN=" + username +", OU=UESTC, O=UESTC, L=Chengdu, ST=Sichuan, C=CN";
X500Name owner = new X500Name(name);
X509CertInfo x509CertInfo = new X509CertInfo();
x509CertInfo.set(X509CertInfo.VERSION, new CertificateVersion(1));
x509CertInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber((int) (System.currentTimeMillis() / 1000L)));
Signature signature = Signature.getInstance("MD5WithRSA");
X500Signer signer = new X500Signer(signature, x500Name);
AlgorithmId algorithmId = signer.getAlgorithmId();
x509CertInfo.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algorithmId));
x509CertInfo.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
x509CertInfo.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic()));
CertificateValidity interval = new CertificateValidity(new Date(), new Date(System.currentTimeMillis() + 365000000000L));
x509CertInfo.set(X509CertInfo.VALIDITY, interval);
x509CertInfo.set(X509CertInfo.ISSUER, new CertificateIssuerName(signer.getSigner()));
X509CertImpl x509CertImpl = new X509CertImpl(x509CertInfo);
x509CertImpl.sign(pk, "MD5WithRSA");
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream in = new FileInputStream("E:/workspace/CurriculumDesign/src/main/resources/identity.jks");
String storePass = "123456";
ks.load(in, storePass.toCharArray());
in.close();
ks.setCertificateEntry(username,x509CertImpl);
FileOutputStream out = new FileOutputStream(new File("E:/workspace/CurriculumDesign/src/main/resources/identity.jks"));
ks.store(out, storePass.toCharArray());
out.close();
3.证书导出
/*
*从证书库中导出用户的证书文件:username为用户名
*/
String storePass = "123456";
KeyStore ks = KeyStore.getInstance("JKS");
FileInputStream in = new FileInputStream("E:/workspace/CurriculumDesign/src/main/resources/identity.jks");
ks.load(in,storePass.toCharArray());
Certificate cert = ks.getCertificate(username);
byte[] encoded = cert.getEncoded();
in.close();
Writer writer = new OutputStreamWriter( new FileOutputStream(basePath + "/" + username + ".cer"));
writer.write( new BASE64Encoder().encode(encoded));
writer.close();
System.out.println("导出"+username+"证书成功");
4.证书下载
/*
*文件下载可以直接使用文件的物理路径,但是这样就暴露了服务器目录信息
*下面使用的是流式文件下载,将文件写入到http响应输出流中
*/
@RequestMapping("/download")
public void download(HttpServletRequest request,HttpServletResponse response){
String basePath = request.getSession().getServletContext().getRealPath("/WEB-INF/upload");
String fileName = ((Student)request.getSession().getAttribute("student")).getUsername() + ".cer";
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader("Content-Disposition", "attachment;fileName="+fileName);
try {
File file=new File(basePath + "/" + fileName);
InputStream inputStream=new FileInputStream(file);
OutputStream os=response.getOutputStream();
byte[] b=new byte[1024];
int length;
while((length=inputStream.read(b))>0){
os.write(b,0,length);
}
inputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
blog comments powered by Disqus
Published
03 June 2013