I am looking for a procedure of enrolling a certificate.
I have searched a lot but didn't find a good answer. Till now I get that firstly I have to generate a Key store (For creating a public key and a private key) then private key should be kept private and public key is sent with other information (like name and organization) to the CA. Then the CA will generate something and give me back something which contains the public key and information.
What does the CA generate? What is a P12 file and what does a .cer file contain?
Certificate enrollment refers to the process by which a user requests a digital certificate to use as a machine identity on a public-facing system, application, API, container or cluster.
Go to Computer Configuration > Windows Settings > Security Settings, and then click Public Key Policies. Enable the Certificate Services Client - Auto-Enrollment policy to match the settings in the following screenshot. Enable Certificate Services Client - Certificate Enrollment Policy.
This one allows users to enroll for certificates with no user intervention needed (well, in most cases, that is). Long story short, Microsoft certificate auto-enrollment automates the whole process and allows certificates to be automatically renewed and updated.
The Certificate Enrollment Web Service is an Active Directory Certificate Services (AD CS) role service that enables users and computers to perform certificate enrollment by using the HTTPS protocol.
The general procedure to issue certificates in a Public Key Infrastructure is more or less the following:
the client generates a key pair, private and public
the client generates a CSR (Certificate Signing Request) including attributes like Common Name and the Public Key. Signs it with the private key and sends it to the server
The server builds the X509 Certificate with the CSR data, signs it with the CA private key and returns the X509 to client
the client stores the private key and the certificate in a KeyStore
What CA generate?
The x509 certificate
What is P12 file
A file in PKCS#12 format (.pfx or .p12) containing a key store
what is .cer file contain
The public part of the certificate (not private key) in DER or PEM format
Gradle dependencies
compile 'com.madgag.spongycastle:core:1.51.0.0'
compile 'com.madgag.spongycastle:pkix:1.51.0.0'
Generate KeyPair and CSR
//Generate KeyPair
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(KEY_SIZE, new SecureRandom());
KeyPair keyPair = keyGen.generateKeyPair();
//Generate CSR in PKCS#10 format encoded in DER
PKCS10CertificationRequest csr = CsrHelper.generateCSR(keyPair, commonname);
byte CSRder[] = csr.getEncoded();
Utilities
public class CsrHelper {
private final static String DEFAULT_SIGNATURE_ALGORITHM = "SHA256withRSA";
private final static String CN_PATTERN = "CN=%s, O=Aralink, OU=OrgUnit";
private static class JCESigner implements ContentSigner {
private static Map<String, AlgorithmIdentifier> ALGOS = new HashMap<String, AlgorithmIdentifier>();
static {
ALGOS.put("SHA256withRSA".toLowerCase(), new AlgorithmIdentifier(
new ASN1ObjectIdentifier("1.2.840.113549.1.1.11")));
ALGOS.put("SHA1withRSA".toLowerCase(), new AlgorithmIdentifier(
new ASN1ObjectIdentifier("1.2.840.113549.1.1.5")));
}
private String mAlgo;
private Signature signature;
private ByteArrayOutputStream outputStream;
public JCESigner(PrivateKey privateKey, String sigAlgo) {
//Utils.throwIfNull(privateKey, sigAlgo);
mAlgo = sigAlgo.toLowerCase();
try {
this.outputStream = new ByteArrayOutputStream();
this.signature = Signature.getInstance(sigAlgo);
this.signature.initSign(privateKey);
} catch (GeneralSecurityException gse) {
throw new IllegalArgumentException(gse.getMessage());
}
}
@Override
public AlgorithmIdentifier getAlgorithmIdentifier() {
AlgorithmIdentifier id = ALGOS.get(mAlgo);
if (id == null) {
throw new IllegalArgumentException("Does not support algo: " +
mAlgo);
}
return id;
}
@Override
public OutputStream getOutputStream() {
return outputStream;
}
@Override
public byte[] getSignature() {
try {
signature.update(outputStream.toByteArray());
return signature.sign();
} catch (GeneralSecurityException gse) {
gse.printStackTrace();
return null;
}
}
}
//Create the certificate signing request (CSR) from private and public keys
public static PKCS10CertificationRequest generateCSR(KeyPair keyPair, String cn) throws IOException,
OperatorCreationException {
String principal = String.format(CN_PATTERN, cn);
ContentSigner signer = new JCESigner (keyPair.getPrivate(),DEFAULT_SIGNATURE_ALGORITHM);
PKCS10CertificationRequestBuilder csrBuilder = new JcaPKCS10CertificationRequestBuilder(
new X500Name(principal), keyPair.getPublic());
ExtensionsGenerator extensionsGenerator = new ExtensionsGenerator();
extensionsGenerator.addExtension(Extension.basicConstraints, true, new BasicConstraints(
true));
csrBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest,
extensionsGenerator.generate());
PKCS10CertificationRequest csr = csrBuilder.build(signer);
return csr;
}
}
To add on to pedrofb's answer you can also use SpongyCastle's JcaContentSignerBuilder
instead of JCESigner
which will condense your code considerably.
Utilities:
private final static String CN_PATTERN = "CN=%s, O=Aralink, OU=OrgUnit";
//Create the certificate signing request (CSR) from private and public keys
public static PKCS10CertificationRequest generateCSR(KeyPair keyPair, String cn) throws IOException, OperatorCreationException {
String principal = String.format(CN_PATTERN, cn);
ContentSigner signer = new JcaContentSignerBuilder(DEFAULT_RSA_SIGNATURE_ALGORITHM).build(keyPair.getPrivate());
PKCS10CertificationRequestBuilder csrBuilder = new JcaPKCS10CertificationRequestBuilder(
new X500Name(principal), keyPair.getPublic());
ExtensionsGenerator extensionsGenerator = new ExtensionsGenerator();
extensionsGenerator.addExtension(Extension.basicConstraints, true, new BasicConstraints(
true));
csrBuilder.addAttribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest,
extensionsGenerator.generate());
PKCS10CertificationRequest csr = csrBuilder.build(signer);
return csr;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With