本周任务
- 对项目进行完善总结
完成情况
针对上周的测试代码进行分类,并写出主类
- UML类图
- 上半部分(前面好像看不清)
- 左半部分
- 右半部分
每个类的描述
CertConv
- 主类
- 输入证书类型
- 并通过
JudgeCert
对象判断转换的类型,以进行下一步的操作
import java.security.cert.X509Certificate;
import java.util.Scanner;
public class CertConv {
public static void main(String[] args) throws Exception {
JudgeCert judgeCert = new JudgeCert();
System.out.println("请输入源证书格式:");
Scanner scanner1 = new Scanner(System.in);
String certSrc = scanner1.nextLine();
X509Certificate certificate = judgeCert.readCert(certSrc);
System.out.println("请输入目标证书格式:");
Scanner scanner2 = new Scanner(System.in);
String certDst = scanner2.nextLine();
judgeCert.writeCert(certDst,certificate);
}
}
JudgeCert
-
方法
readCert()
:判断源证书格式,并调用ReadXXX
类,将其转换为X509Certificate
对象 -
方法
writeCert()
:判断源证书格式,并调用WriteXXX
类,将X509Certificate
对象转换为目标格式证书
import org.bouncycastle.util.io.pem.PemObject;
import read.*;
import wirte.WriteDer;
import wirte.WritePem;
import wirte.WritePfx;
import java.io.IOException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.util.Scanner;
public class JudgeCert {
public X509Certificate readCert(String certSrc) throws Exception {
System.out.println("请输入源证书地址(形如:C:\Users\Administrator\ca.cer):");
Scanner scanner = new Scanner(System.in);
String pathSrc = scanner.nextLine();
String s = pathSrc.substring(pathSrc.length() - 3);
X509Certificate certificate = null;
if (certSrc.toLowerCase().equals("pem")) {
if (!((s.equals("pem"))||(s.equals("crt"))||(s.equals("cer")))){
System.out.println("输入错误!");
System.exit(-1);
}
ReadPem readPem = new ReadPem();
PemObject pemObject = readPem.getPem(pathSrc);
byte[] b = readPem.getByte(pemObject);
certificate = readPem.getX509(b);
}
else if (certSrc.toLowerCase().equals("pfx")) {
if (!(s.equals("pfx")||s.equals("p12"))){
System.out.println("输入错误!");
System.exit(-1);
}
System.out.println("请输入密码:");
Scanner scanner1 = new Scanner(System.in);
char[] passwd = scanner1.nextLine().toCharArray();
ReadPfx readPfx = new ReadPfx();
certificate = readPfx.getX509(pathSrc,passwd);
}
else if (certSrc.toLowerCase().equals("der")) {
if (!(s.equals("der"))){
System.out.println("输入错误!");
System.exit(-1);
}
ReadDer reader = new ReadDer();
certificate = reader.getX509(pathSrc);
}
else if (certSrc.toLowerCase().equals("p7b")) {
if (!(s.equals("p7b")||s.equals("p7c"))){
System.out.println("输入错误!");
System.exit(-1);
}
ReadP7b readP7b = new ReadP7b();
byte[] b = readP7b.getByte(pathSrc);
certificate = readP7b.readCertificatesFromPKCS7(b);
}
else {
System.out.println("输入错误!");
System.exit(-1);
}
return certificate;
}
public void writeCert(String certDst,X509Certificate certificate) throws IOException, CertificateException, InvalidKeySpecException, NoSuchAlgorithmException, KeyStoreException {
System.out.println("请输入目标证书地址(形如:C:\Users\Administrator\ca.cer):");
Scanner scanner = new Scanner(System.in);
String pathDst = scanner.nextLine();
String s = pathDst.substring(pathDst.length() - 3);
if (certDst.toLowerCase().equals("pem")) {
if (!((s.equals("pem"))||(s.equals("crt"))||(s.equals("cer")))){
System.out.println("输入错误!");
System.exit(-1);
}
WritePem writePem = new WritePem();
writePem.writePem(pathDst,certificate);
}
else if (certDst.toLowerCase().equals("pfx")) {
if (!(s.equals("pfx")||s.equals("p12"))){
System.out.println("输入错误!");
System.exit(-1);
}
System.out.println("请输入密码:");
Scanner scanner1 = new Scanner(System.in);
char[] passwd = scanner1.nextLine().toCharArray();
System.out.println("请输入您的私钥位置(形如:C:\Users\Administrator\ca.cer):");
Scanner scanner2 = new Scanner(System.in);
String pathKey = scanner2.nextLine();
String s1 = pathKey.substring(pathKey.length() - 3);
if (!(s1.equals("pem"))){
System.out.println("输入错误!");
System.exit(-1);
}
ReadKey readKey = new ReadKey();
byte[] b = readKey.getByte(pathKey);
PrivateKey privateKey = readKey.readKey(b);
WritePfx writePfx = new WritePfx();
writePfx.setStore(certificate,privateKey,passwd);
writePfx.writePfx(pathDst,passwd);
}
else if (certDst.toLowerCase().equals("der")) {
if (!(s.equals("der"))){
System.out.println("输入错误!");
System.exit(-1);
}
WriteDer writeDer = new WriteDer();
writeDer.writeDer(pathDst,certificate);
}
else {
System.out.println("输入错误!");
System.exit(-1);
}
}
}
ReadXXX
- 主要是将各种形式的证书统一转换为
X509Certificate
对象,以便进一步转换
以ReadPem为例
- 使用BouncyCastle的
PemReader
类,从PEM格式的证书中读取PemObject
对象,并将其转化为X509Certificate
证书对象
package read;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import java.io.ByteArrayInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
public class ReadPem {
public PemObject getPem(String path) throws IOException {
Security.addProvider( new BouncyCastleProvider() );
PemReader reader = new PemReader( new FileReader( path ) );
Object pemObject = reader.readPemObject();
PemObject p = (PemObject)pemObject;
return p;
}
public byte[] getByte(PemObject p){
return p.getContent();
}
public X509Certificate getX509(byte[] b) throws CertificateException {
return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(new ByteArrayInputStream(b));
}
}
WriteXXX
- 主要是将
X509Certificate
证书对象进行一些转换,输出为各种类型的证书
以WritePem为例
- 将
X509Certificate
证书对象使用Base64进行编码,之后使用BouncyCastle的PemWriter
类生成PEM证书
package wirte;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
public class WritePem {
public void writePem(String path,X509Certificate certificate) throws CertificateEncodingException, IOException {
PemObject pemObject = new PemObject("CERTIFICATE", certificate.getEncoded());
StringWriter str = new StringWriter();
PemWriter pemWriter = new PemWriter(str);
pemWriter.writeObject(pemObject);
pemWriter.close();
str.close();
FileOutputStream certOut = new FileOutputStream(path);
certOut.write(str.toString().getBytes());
System.out.println("转换成功!");
}
}
边界检测
证书格式输入控制
- 在
JudgeCert
类中,使用if条件语句判断输入的证书格式是否正确
证书位置输入控制
- 使用
String
类的substring
提取证书位置后三位
- 验证后三位是否符合之前输入的证书格式
私钥位置输入控制
- 提取私钥位置后三位,验证是否符合要求