玖叶教程网

前端编程开发入门

Java,安全,自签名证书、Java代码实现颁发数字证书

自签名证书

自签证书(自颁发证书),由签名实体发布给自身的证书,即发布者和证书主体相同,是同一个CA的证书。

自颁发(签发)证书的一种特殊情形,由CA使用其私钥来对证书进行签名,而相应公钥就在证书中。

根CA的数字证书,由自己签发,就属于自签名证书。

颁发数字证书

定义:CA证书是由一个CA颁发给另一个CA的证书。

生成根证书

keytool -genkey -dname "CN=XFDServer,OU=XFDUnit,O=XFD,L=TaiYuan, ST=ShanXi, C=CN" -keysize 2048 -alias server -keyalg RSA -keystore d:/server.jks -keypass 123456 -storepass 123456 -validity 36500

颁发数字证书代码

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;

import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.*;
import java.security.cert.Certificate;
import java.util.Date;
import java.util.List;

public class IssueCertificate {

    static final String keyStoreType = "JKS";
    // key长度
    static final int keysize = 2048;

    /**
     * 从CA证书的JKS文件中读取私钥
     *
     * @param storeFile
     * @param storePasswd
     * @param caAlias
     * @param trustPasswd
     * @return
     * @throws Exception
     */
    public static KeyStore.PrivateKeyEntry getRootPrivateKey(String storeFile, String storePasswd, String caAlias, String trustPasswd) throws Exception {
        KeyStore store = KeyStore.getInstance(keyStoreType);
        store.load(new FileInputStream(storeFile), storePasswd.toCharArray());
        char[] trustCPW = trustPasswd.toCharArray();
        KeyStore.PasswordProtection passwordProtection = new KeyStore.PasswordProtection(trustCPW);
        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) store.getEntry(caAlias, passwordProtection);
        return privateKeyEntry;
    }

    public static void issueCertificate(KeyStore.PrivateKeyEntry privateKeyEntry, String alias, String subject, String trustPasswd, int validityYear,
                                        String trustPath) throws Exception {
        // 生成秘钥对
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
        kpg.initialize(keysize);
        KeyPair keyPair = kpg.generateKeyPair();
        KeyStore store = KeyStore.getInstance(keyStoreType);
        store.load(null, null);
        // 颁发者
        X509Certificate caCert = (X509Certificate) privateKeyEntry.getCertificate();
        // 颁发者
        String issuer = caCert.getIssuerDN().toString();
        Date notBefore = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24);
        Date notAfter = new Date(System.currentTimeMillis() + 1000L * 60 * 60 * 24 * 365 * validityYear);
        Certificate signCert = generateV3(issuer, subject, BigInteger.ZERO, notBefore, notAfter, keyPair.getPublic(), privateKeyEntry.getPrivateKey(), null);
        // 输出证书
        makeSignCert(keyPair, alias, signCert, privateKeyEntry.getCertificate(), trustPasswd, trustPath);
    }

    /**
     * 输出证书
     *
     * @param keyPair
     * @param alias
     * @param signCert
     * @param caCert
     * @param trustPasswd
     * @param trustPath
     * @throws Exception
     */
    private static void makeSignCert(KeyPair keyPair, String alias, Certificate signCert, Certificate caCert, String trustPasswd, String trustPath) throws Exception {
        KeyStore signStore = KeyStore.getInstance(keyStoreType);
        signStore.load(null, null);
        signStore.setKeyEntry(alias, keyPair.getPrivate(), trustPasswd.toCharArray(), new Certificate[]{signCert, caCert});
        File file = new File(trustPath);
        if (file.exists() || file.createNewFile()) {
            signStore.store(new FileOutputStream(file), trustPasswd.toCharArray());
        }
    }

    /**
     * @param issuer
     * @param subject
     * @param serial
     * @param notBefore
     * @param notAfter
     * @param publicKey
     * @param privateKey
     * @param extensions
     * @return
     * @throws Exception
     */
    private static Certificate generateV3(String issuer, String subject, BigInteger serial, Date notBefore, Date notAfter,
                                          PublicKey publicKey, PrivateKey privateKey, List<Extension> extensions) throws Exception {
        // X500Name var1, BigInteger var2, Date var3, Date var4, X500Name var5, PublicKey var6
        X500Name var1 = new X500Name(issuer);
        X500Name var5 = new X500Name(subject);
        X509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(var1, serial, notBefore, notAfter, var5, publicKey);
        ContentSigner contentSigner = new JcaContentSignerBuilder("SHA1withRSA").build(privateKey);
        // privateKey是CA的私钥,publicKey是待签名的公钥,那么生成的证书就是被CA签名的证书
        if (extensions != null)
            for (Extension ext : extensions) {
                builder.addExtension(new ASN1ObjectIdentifier(ext.getId()), ext.isCritical(), ASN1Primitive.fromByteArray(ext.getValue()));
            }
        X509CertificateHolder holder = builder.build(contentSigner);
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        InputStream is1 = new ByteArrayInputStream(holder.toASN1Structure().getEncoded());
        X509Certificate theCert = (X509Certificate) certificateFactory.generateCertificate(is1);
        is1.close();
        return theCert;
    }


}
import java.security.KeyStore;

public class IssueCertificateClient {

    public static void main(String[] args) {
        // 生成根证书
        // keytool -genkey -dname "CN=XFDServer,OU=XFDUnit,O=XFD,L=TaiYuan, ST=ShanXi, C=CN" -keysize 2048 -alias server -keyalg RSA -keystore d:/server.jks -keypass 123456 -storepass 123456 -validity 36500
        String storeFile = "d:/server.jks";
        String storePasswd = "123456";
        String caAlias = "server";
        String trustPasswd = "123456";
        KeyStore.PrivateKeyEntry rootPrivateKeyEntry = null;
        try {
            rootPrivateKeyEntry = IssueCertificate.getRootPrivateKey(storeFile, storePasswd, caAlias, trustPasswd);
        } catch (Exception e) {
            e.printStackTrace();
        }
        String alias = "client1";
        String subjects = "C=CN,ST=ShanXi,L=TaiYuan,O=XFD,OU=XFDUnit,CN=XFDClient1";
        String signTrustPasswd = "123456";
        int validityYears = 10;
        String trustPath = "d:/client1.jks";
        try {
            IssueCertificate.issueCertificate(rootPrivateKeyEntry, alias, subjects, signTrustPasswd, validityYears, trustPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("颁发证书完成.");
        // keytool -export -alias client1 -keystore d:/client1.jks -file d:/client1.crt -storepass 123456
    }

}

生成crt证书

keytool -export -alias client1 -keystore d:/client1.jks -file d:/client1.crt -storepass 123456

查看颁发证书

keytool -list -rfc -keystore d:/client1.jks -storepass 123456

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言