2020_1课程设计—基于BC的证书格式转换工具的设计与实现—Week3
2020_1课程设计—基于BC的证书格式转换工具的设计与实现—Week3
目录
任务要求
- 清楚.pem .pfx /.keystore .crt .cer .der 这些格式的文件用openssl如何产生
- 使用OpenSSL命令行查看证书,并实现证书格式转换
- 清楚哪些格式可以互相转换,并使用BouncyCastle编程实现
Week3 任务安排
- 对项目代码进行完善总结
- 消除代码冗余、重复的情况
- 增加边界控制
- 将输入部分写活
- 形成一个证书转换系统
- 设计编写图形化界面
实践过程
加载证书类
readDer
- 使用文件读入流读取DER格式证书
- 将读取的证书写入字节数组中
- 将字节数组转化为X509标准格式的证书
- 返回该X509格式证书
//读DER证书
File file = new File(path);
long filesize = file.length();
FileInputStream fis = new FileInputStream(file);
byte[] cert = new byte[(int) filesize];
int offset = 0;
int numRead = 0;
while (offset < cert.length
&& (numRead = fis.read(cert, offset, cert.length - offset)) >= 0) {
offset += numRead;
}
fis.close();
//输出X509格式证书
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");//获取工厂实例
Certificate certificate = certificateFactory.generateCertificate(new ByteArrayInputStream(cert));//用文件流读入证书
X509Certificate x509Certificate = (X509Certificate)certificate;
return x509Certificate;
readPem
- 使用BC中的PemReader方法加载证书
- 将读取的证书写入字节数组中
- 将字节数组转化为X509标准格式的证书
- 返回该X509格式证书
//加载BC
Security.addProvider( new BouncyCastleProvider() );
//使用BC提供的Pemreader读证书
PemReader pemReader = new PemReader( new FileReader( "E:\\认真的侯颖好好看(课内)\\大三下\\课设\\certificate\\test.pem" ) );
PemObject pemObject = pemReader.readPemObject();
byte cert[] = pemObject.getContent();
//输出X509格式证书
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");//获取工厂实例
Certificate certificate = certificateFactory.generateCertificate(new ByteArrayInputStream(cert));//用文件流读入证书
X509Certificate x509Certificate = (X509Certificate)certificate;
System.out.println(x509Certificate);
return x509Certificate;
readKey
- 使用BC中的PemReader方法加载证书
- 将读取的私钥写入字节数组中
- 使用给定的编码密钥创建新的 PKCS8EncodedKeySpec
- 创建一个密钥工厂对象就可以按照要求生成一个RSA私钥
//读密钥
PemReader pemReader_key = new PemReader(new FileReader(path));
PemObject pemObject1 = pemReader_key.readPemObject();
byte[] keyByte = pemObject1.getContent();
//加密私钥
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyByte);//使用给定的编码密钥创建新的 PKCS8EncodedKeySpec
KeyFactory keyFactory = KeyFactory.getInstance("RSA");//创建一个密钥工厂对象就可以按照要求生成一个RSA私钥
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
readPfx
- 使用文件读入流读取PFX格式证书
- PFX格式证书含私钥,从给定的输入流加载密钥库
- 使用给定的编码密钥创建新的 PKCS8EncodedKeySpec
- 创建一个密钥工厂对象就可以按照要求生成一个RSA私钥
- 返回该X509格式证书
//读PFX证书,用密钥解密证书
FileInputStream fs = new FileInputStream(path);
PKCS12KeyStore store = new PKCS12KeyStore();
store.engineLoad(fs,passwd);//从给定的输入流加载密钥库
fs.close();
//生成x509格式读证书
Enumeration enumas = store.engineAliases();
String keyAlias = null;
if (enumas.hasMoreElements())
{
keyAlias = (String)enumas.nextElement();
System.out.println("alias=[" + keyAlias + "]");
}
Certificate cert = store.engineGetCertificate(keyAlias);
X509Certificate x509Certificate = (X509Certificate)cert;
System.out.println(x509Certificate);
return x509Certificate;
转换证书,并写入文件
writeDer
- DER是二进制文件,因此需要将X509格式证书进行编码
- 将转化之后的数组写入文件即可
byte[] cert = x509Certificate.getEncoded();
File file=new File(path);
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(cert);
fos.close();
System.out.println("Successful!");
writePem
- 将X509格式证书进行编码
- 使用BC中的PemWriter方法转换证书格式
- 将转化之后的数组写入文件即可
//加载BC
Security.addProvider( new BouncyCastleProvider() );
//BC转化PEM格式证书
StringWriter str = new StringWriter();
PemWriter pemWriter = new PemWriter(str);
pemWriter.writeObject(new PemObject("CERTIFICATE",x509Certificate.getEncoded()));
pemWriter.close();
str.close();
//写入文件
FileOutputStream fos = new FileOutputStream(path);
fos.write(str.toString().getBytes());
System.out.println("Successful!");
writePfx
- 将给定的证书分配给给定的别名
- PFX证书中含私钥,将私钥写入证书中
- 将转化之后的数组写入文件即可
- 因为PFX证书中含私钥,需要用密钥保护,因此需将密钥和证书文件绑定
//证书链
X509Certificate[] chain = new X509Certificate[1];
chain[0]= x509Certificate;
//PFX证书转换
PKCS12KeyStore store = new PKCS12KeyStore();
store.engineSetCertificateEntry( "CA's Primary Certificate", x509Certificate );
store.engineSetKeyEntry( "CA's Primary Certificate",privateKey, storePwd,chain);
FileOutputStream out = new FileOutputStream( path );
store.engineStore(out,storePwd );
out.close();
System.out.println("Successful!");
图形化界面
- 通过编写网页实现图形化界面
- 通过form表单实现前端后台的数据交互
- 将命令行输入文件路径改为图形化直接家在本地文件
- 将之前在后台进行的边界测试、输入要求等移到前端进行
- 通过表单中的button触发js进行证书格式判断
- 后台通过
request.getParameter()
获取前端数据