I have the following scenario: I have a lot of embedded devices that should talk to another. To enable trust between these devices I would like to use certificates. The devices generate a keypair and send the public key to a central instance that should act as enrollment agent, request the corresponding certificate for the public key from the CA and send it back to the client.

To my limited understanding it should be possible to request a certificate for another user/machine if

a) I'm in possession of an enrollment agent certificate, with which I sign the request

b) I have the public key that should be certified by the CA.

Unfortunately everything I found during my research the last days this does not seem to be possible. Can somebody with a deeper understanding than me please shed some light on this?


To make it clearer what I want to achieve and still not know if it's possible, here are the steps:

  1. The device creates a keypair
  2. The device sends the public key of this pair to a machine that acts as an enrollment agent (protected by OTP)
  3. The machine, that acts as enrollment agent, creates a csr for the device containing the public key and signs it with the enrollment agent certificate.
  4. The machine sends the csr to the RA and delivers the resulting certificate to the device.

I hope this clears things up a bit.

The first thing I researched was the automation of the process by using certreq, especially certreq -new. I can see no option to provide the public key of the device to the request.

Then I looked at the example at Creating an Enrollment Agent Signed CMC Request (Single Signer), but I can't see where the public key of the device makes its way into the request.

As I am more familiar with the Java language I also looked in some examples utilizing the bouncycastle API. All of them used the private key corresponding to the public key of the device to sign the request, not the enrollment agent certificate.

I know that the above is a common usecase for smartcards, but I can't find how it is done.

  • It is not quite clear what you're asking for. Can you tell the community what exactly you tried and why "it is not possible"? The more concrete a question is the bigger is the probability that you will get a good answer.
    – kaidentity
    Oct 20, 2016 at 9:49
  • Added more information to the question to clear things up a bit.
    – Frank
    Oct 20, 2016 at 12:28
  • Hey have you heard of let's encrypt? Hers a link to their GitHub for cert bot if you check the other source code related to their project you might find the tools to build what you are asking for. Might also want to brush up on how SSL certs works as it seems you've an incomplete picture.
    – S0AndS0
    Oct 20, 2016 at 13:29

1 Answer 1


Ok, after some struggling I found that this is possible using CMP. Unfortunately the Microsoft CA I used in the beginning seems to ignore some standards so I didn't get it to work.

Using EJBCA did the trick. I was able to do exactly what I want following the code snippets in the documentation. Just setting the ProofOfPossession-flag to RAVerified helped to achieve the desired behaviour. Here's a codesnippet using the bouncycastle-library:

    CertificateRequestMessageBuilder msgbuilder = new CertificateRequestMessageBuilder(certReqId);
    X500Name issuerDN = new X500Name(issuerDNString);
    X500Name subjectDN = new X500Name(subjectDNString);
    final byte[] bytes = keyPair.getPublic().getEncoded();
    final ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);
    final ASN1InputStream dIn = new ASN1InputStream(bIn);
    final SubjectPublicKeyInfo keyInfo = SubjectPublicKeyInfo.getInstance((ASN1Sequence) dIn.readObject());
    GeneralName sender = new GeneralName(subjectDN);
    // RAVerified POP

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.