Monday, July 3, 2017

Java and SSL: Signing a CSR with Java

This post is part of a series about the worlds of Java and SSL.  I hope to do 1 post a day on this topic. The resulting posts will become the basis for another section of a talk that I am scheduled to give on August 10 at the Boulder/Denver Cybersecurity Meetup.

public static X509Certificate sign(PrivateKey caPrivate, PublicKey signeePublic,
                                   X500Name issuer, Date notValidBefore, Date notValidAfter, BigInteger serialNumber,
                                   X500Name subject)
        throws InvalidKeyException, NoSuchAlgorithmException,
        NoSuchProviderException, SignatureException, IOException,
        OperatorCreationException, CertificateException {

    AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder()
            .find("SHA1withRSA");
    AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder()
            .find(sigAlgId);

    AsymmetricKeyParameter foo = PrivateKeyFactory.createKey(caPrivate.getEncoded());
    SubjectPublicKeyInfo keyInfo = SubjectPublicKeyInfo.getInstance(signeePublic.getEncoded());
        
    org.bouncycastle.asn1.x500.X500Name bcIssuer = new org.bouncycastle.asn1.x500.X500Name(issuer.getName());
    org.bouncycastle.asn1.x500.X500Name bcSubject = new org.bouncycastle.asn1.x500.X500Name(subject.getName());
    X509v3CertificateBuilder myCertificateGenerator = new X509v3CertificateBuilder(bcIssuer, serialNumber, 
            notValidBefore, notValidAfter, bcSubject, keyInfo);
        
    ContentSigner sigGen = new BcRSAContentSignerBuilder(sigAlgId, digAlgId)
            .build(foo);

    X509CertificateHolder holder = myCertificateGenerator.build(sigGen);
    X509CertificateStructure eeX509CertificateStructure = holder.toASN1Structure();

    CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");

    InputStream is1 = new ByteArrayInputStream(eeX509CertificateStructure.getEncoded());
    X509Certificate theCert = (X509Certificate) cf.generateCertificate(is1);
    is1.close();
    return theCert;
}


This is complex...and it really shouldn't be.  But at least there is a way to do this in Java.

No comments:

Post a Comment