2020_1课程设计—基于BC的证书格式转换工具的设计与实现—第三周进展

本周任务

  • 对项目进行完善总结

完成情况

针对上周的测试代码进行分类,并写出主类

  • 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提取证书位置后三位

  • 验证后三位是否符合之前输入的证书格式

私钥位置输入控制

  • 提取私钥位置后三位,验证是否符合要求

posted @ 2020-04-29 01:45  20175217wyf  阅读(248)  评论(0编辑  收藏  举报