SSL证书生成过程

SSL证书结构

结构图

SSL证书生成过程_第1张图片
SSL_ctf_struct.jpg

SSL证书包括两部分,证书信息和签名信息,签名信息在证书合法性形校验使用。

根证书生成

SSL证书生成过程_第2张图片
根证书生成过程-2.jpg

根证书的生成分为三个部分:

  • 生成根证书的公钥和私钥
  • 构建证书的原始证书,包括公钥、加密算法、生效时间、过期时间等信息。
  • 用根证书私钥对原始证书进行签名,生成合法的根证书。
  • 根证书安装,将根证书安装到客户端,比如手机、电脑中。
    代码
 //生成证书
    public static KeyStore createRootCertificate(Authority authority,
            String keyStoreType) throws NoSuchAlgorithmException,
            NoSuchProviderException, IOException,
            OperatorCreationException, CertificateException, KeyStoreException {
        //生成公钥和私钥
        KeyPair keyPair = generateKeyPair(ROOT_KEYSIZE);
        //生成证书
        X500NameBuilder nameBuilder = new X500NameBuilder(BCStyle.INSTANCE);
        nameBuilder.addRDN(BCStyle.CN, authority.commonName());
        nameBuilder.addRDN(BCStyle.O, authority.organization());
        nameBuilder.addRDN(BCStyle.OU, authority.organizationalUnitName());

        X500Name issuer = nameBuilder.build();
        BigInteger serial = BigInteger.valueOf(initRandomSerial());
        X500Name subject = issuer;
        PublicKey pubKey = keyPair.getPublic();

        X509v3CertificateBuilder generator = new JcaX509v3CertificateBuilder(
                issuer, serial, NOT_BEFORE, NOT_AFTER, subject, pubKey);

        generator.addExtension(Extension.subjectKeyIdentifier, false,
                createSubjectKeyIdentifier(pubKey));
        generator.addExtension(Extension.basicConstraints, true,
                new BasicConstraints(true));

        KeyUsage usage = new KeyUsage(KeyUsage.keyCertSign
                | KeyUsage.digitalSignature | KeyUsage.keyEncipherment
                | KeyUsage.dataEncipherment | KeyUsage.cRLSign);
        generator.addExtension(Extension.keyUsage, false, usage);

        ASN1EncodableVector purposes = new ASN1EncodableVector();
        purposes.add(KeyPurposeId.id_kp_serverAuth);
        purposes.add(KeyPurposeId.id_kp_clientAuth);
        purposes.add(KeyPurposeId.anyExtendedKeyUsage);
        generator.addExtension(Extension.extendedKeyUsage, false,
                new DERSequence(purposes));

        X509Certificate cert = signCertificate(generator, keyPair.getPrivate());

        KeyStore result = KeyStore
                .getInstance(keyStoreType/* , PROVIDER_NAME */);
        result.load(null, null);
        result.setKeyEntry(authority.alias(), keyPair.getPrivate(),
                authority.password(), new Certificate[] { cert });
        return result;
    }

服务器证书生成

SSL证书生成过程_第3张图片
服务器证书生成过程.jpg

服务器证书的生成过程与根证书类似,只是给服务器原始证书签名的不是自己生成的私钥,而是根证书的私钥。

public static KeyStore createServerCertificate(String commonName,
            SubjectAlternativeNameHolder subjectAlternativeNames,
            Authority authority, Certificate caCert, PrivateKey caPrivKey)
            throws NoSuchAlgorithmException, NoSuchProviderException,
            IOException, OperatorCreationException, CertificateException,
            InvalidKeyException, SignatureException, KeyStoreException {

        KeyPair keyPair = generateKeyPair(FAKE_KEYSIZE);

        X500Name issuer = new X509CertificateHolder(caCert.getEncoded())
                .getSubject();
        BigInteger serial = BigInteger.valueOf(initRandomSerial());

        X500NameBuilder name = new X500NameBuilder(BCStyle.INSTANCE);
        name.addRDN(BCStyle.CN, commonName);
        name.addRDN(BCStyle.O, authority.certOrganisation());
        name.addRDN(BCStyle.OU, authority.certOrganizationalUnitName());
        X500Name subject = name.build();

        X509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(issuer, serial, NOT_BEFORE,
                new Date(System.currentTimeMillis() + ONE_DAY), subject, keyPair.getPublic());

        builder.addExtension(Extension.subjectKeyIdentifier, false,
                createSubjectKeyIdentifier(keyPair.getPublic()));
        builder.addExtension(Extension.basicConstraints, false,
                new BasicConstraints(false));

        subjectAlternativeNames.fillInto(builder);

        X509Certificate cert = signCertificate(builder, caPrivKey);

        cert.checkValidity(new Date());
        cert.verify(caCert.getPublicKey());

        KeyStore result = KeyStore.getInstance(KeyStore.getDefaultType()
        /* , PROVIDER_NAME */);
        result.load(null, null);
        Certificate[] chain = { cert, caCert };
        result.setKeyEntry(authority.alias(), keyPair.getPrivate(),
                authority.password(), chain);

        return result;
    }

客户端证书校验过程

  • 客户端收到服务端发送的服务器SSL证书。
  • 解析获得服务器证书的颁发者
  • 找到已安装在客户端的颁发者根证书,如果没找到则服务器证书非法,停止校验。
  • 用根证书的公钥解析服务器证书的签名信息,完成解析认证成功,否则失败。

你可能感兴趣的:(SSL证书生成过程)