2

How to create a X.509 certificate with OpenSSL from just a public key?

In this scenario, I only have the to-be-certified public key (PEM format), and I need to create a X.509 certificate from this. This given public key shall be in the SubjectPublicKeyInfo of the X.509 certificate. The private key for the to-be-certified public key is not available in this scenario!

But, of course, the issuer (CA) key, which shall be used to sign the certificate, is available – including the private key. I understand that I need a private key to sign the certificate 😏

Now, I understand that the to-be-certified public key is usually wrapped in a CSR. And that the CSR is usually signed by the private key for the to-be-certified public key. But, as said before, I do not have a CSR here, just the "plain" to-be-certified public key. Technically, this should not be a problem at all. But can OpenSSL create a X.509 certificate this way somehow?

The closest thing I have found is:

openssl x509 -new -key ca_key.pem -force_pubkey tbs_pubkey.pem -subj "/CN=Test" 

Unfortunately, the above command generates what looks like a "self-signed" certificate that contains the public key from tbs_pubkey.pem and that is signed by the private key from ca_key.pem, so the signature of the resulting "self-signed" certificate is actually invalid... ☹️

2
  • For the OpenSSL command ca the parameter -in filename is defined as "an input filename containing a single certificate request to be signed by the CA." Unfortunately, as I explained before, I do not have a CSR, and also can't create one (without the matching private key). Commented Aug 8, 2024 at 11:20
  • Crossdupe security.stackexchange.com/questions/244602/… and security.stackexchange.com/questions/82284/… (which are more ontopic because OpenSSL is not specific to Unix; it also runs or has run on Windows and MSDOS as well as VMS, OS/360, Guardian, and more) Commented Aug 9, 2024 at 0:29

1 Answer 1

3

Here's a quick and dirty root CA:

openssl req -x509 -newkey rsa:2048 -subj "/CN=My Root CA" -keyout rca.key -out rca.pem -nodes -addext "basicConstraints = critical, CA:true" 

Here is an example of an OpenSSL config file to add extensions to the new certificate:

cat TLS_Cert.cnf [tls] keyUsage = critical,digitalSignature extendedKeyUsage=serverAuth 

Here's my lonely (EC) public key:

cat pubkey.pem -----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE9ZKRcglgL1Af01p+f+SwcLeArN26 nG4mvaH/oRABk0U94V4J+RG0g41Lrxm6MrW7IkqOeEnEqJ0T883H9kPwlg== -----END PUBLIC KEY----- 

Now force it into a certificate, signed by the CA:

openssl x509 -new -CAkey rca.key -CA rca.pem -force_pubkey pubkey.pem -subj "/CN=No Private Key" -extfile TLS_Cert.cnf -extensions tls -out noPrivKey.pem 

The key (excuse the pun) is to use -CAkey and -CA to point OpenSSL at the CA's private key and certificate. The latter's Subject will be used as the Issuer in your new certificate.

openssl x509 -noout -text -in noPrivKey.pem Certificate: Data: Version: 3 (0x2) Serial Number: 78:f9:f9:23:b3:c5:a4:2b:d1:5c:79:bc:90:75:dd:3a:28:74:bc:06 Signature Algorithm: sha256WithRSAEncryption Issuer: CN = My Root CA Validity Not Before: Aug 8 12:23:10 2024 GMT Not After : Sep 7 12:23:10 2024 GMT Subject: CN = No Private Key Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (256 bit) pub: 04:f5:92:91:72:09:60:2f:50:1f:d3:5a:7e:7f:e4: b0:70:b7:80:ac:dd:ba:9c:6e:26:bd:a1:ff:a1:10: 01:93:45:3d:e1:5e:09:f9:11:b4:83:8d:4b:af:19: ba:32:b5:bb:22:4a:8e:78:49:c4:a8:9d:13:f3:cd: c7:f6:43:f0:96 ASN1 OID: prime256v1 NIST CURVE: P-256 X509v3 extensions: X509v3 Key Usage: critical Digital Signature X509v3 Extended Key Usage: TLS Web Server Authentication X509v3 Subject Key Identifier: 30:FB:92:B8:58:63:B5:96:01:58:95:31:13:A3:20:02:F9:EF:EB:8A X509v3 Authority Key Identifier: E5:8C:A8:DD:2F:FC:96:55:3D:EF:60:F5:9E:56:2D:AD:AC:43:0D:6B Signature Algorithm: sha256WithRSAEncryption Signature Value: 07:4f:00:58:6c:07:22:f4:ff:d8:22:d5:36:64:86:c6:9c:84: 1b:45:4b:77:4c:75:09:cd:bb:12:85:88:99:d6:5f:3a:e4:3a: e2:08:e5:46:bc:57:14:51:84:b6:b2:03:e8:e3:5b:da:be:50: 75:a5:59:59:14:ac:12:f4:e4:d6:91:d4:d4:1a:e6:24:45:d8: d9:66:19:dd:a2:ab:d5:b9:d2:8e:2d:03:09:81:ac:0d:46:2c: e1:17:43:de:b9:f5:cd:65:1c:4f:8c:f8:08:43:b7:d4:e1:8f: f2:a8:f7:34:10:d6:c2:24:03:81:4b:d1:74:44:18:8d:69:85: f0:5b:c5:55:cc:84:a3:24:7e:50:67:f2:6b:89:16:da:4e:24: c2:1a:5c:98:aa:f0:4c:c6:cf:03:5d:59:82:20:80:3f:22:74: f0:c1:36:93:22:f9:fe:7f:e9:3b:99:f3:4e:00:22:bc:9b:7a: ba:97:35:8d:d8:42:bf:02:c3:4a:82:6a:db:f5:83:a9:fc:65: 1b:4e:27:a4:e4:85:a2:18:83:6d:d1:4e:d6:db:ff:d8:de:f3: b3:c7:19:e1:7a:15:e9:b3:44:a0:53:8b:9a:6a:3c:ad:68:58: 5f:28:c8:c2:8d:1b:6a:a5:16:6f:05:11:25:67:c5:35:80:3d: b2:aa:6c:aa 

Note the small ECC public key which is signed by the RSA root key. Also, the Subject and Issuer are correct, and the extensions from the file are added.

WARNING:

This is fine for testing, playing etc. but you shouldn't be doing this with a trusted CA certificate as by not using the public key's corresponding private key you are not showing proof of possession of that private key.

The CA should reject such requests as there is no evidence that the public key is owned by the subject.

For more information, see RFC 4211

3
  • 2
    Thank you, so openssl x509 -new with -CA and -force_pubkey is it! I even found that it is possible to store the CA private key and the CA certificate in one file, so that -CAkey is not required. BTW: In this scenario, the to-be-certified public key is generated in a hardware device and there actually is an "attestation" that the public key comes from a key-pair generated in the h/w device. Just not as a CSR in the standard PKCS#10 format that OpenSSL understands ;-) Commented Aug 8, 2024 at 13:03
  • In general the CA should never see the private key; there should be an attestation of ownership via other means (eg for a web site it may be placing a specific file in a specific location, or setting up a DNS value; for an enterprise creating user keys it might be having the user login; there's other ways). Private keys are private and should never be sent to third parties. Commented Aug 8, 2024 at 14:49
  • @StephenHarris - I don't think anyone has suggested that their private keys should be sent anywhere. POP in a PKCS#10 CSR is by signing the request with the private key at the creation point. Or, at least is is for a key which can be used for digital signatures. Commented Aug 8, 2024 at 18:31

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.