ssl: several certificates from single private key? - ssl

I'm trying to create a CA using openssl.
Why do I need to first create a private key:
openssl genrsa -des3 -out ca.key 1024
And then create the certificate?
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
As far as I know, a certificate is a public key signed by a private key?
Where is public key?
Can I then create several certificates from one private key? Does it mean, I'm able to create several public keys?

Related

Trying to generate a pfx from crt and private key from GoDaddy using openssl fails with No certificate matches private key

I'm trying to generate a pfx file from a crt and a private key, and I keep getting No certificate matches private key.
No idea what's going on here.
I did:
openssl pkcs12 -export -out myaudiservice.com.pfx -inkey myaudiservice.com.key -in myaudiservice.com.crt -in gd_bundle-g2-g1.crt
Which gets me:
No certificate matches private key
So, I tried deleting everything, key, crt, cert chain, and then I generated a new CSR:
openssl req -new -newkey rsa:2048 -nodes -keyout myaudiservice.com.key -out myaudiservice.com.csr
Which generated a new key and new csr. I then uploaded the CSR to GoDaddy and requested the cert be re-keyed.
When that was done, I downloaded the new crt, and used the freshly generated key (from the openssl command used to generate the CSR), and I still get the same error.
Then, just as a sanity check I did:
mjb#bohr:~/Downloads/myaudiservice.com$ openssl x509 -noout -modulus -in myaudiservice.com.crt | openssl md5
(stdin)= 36d37e4f8f8672c127178a4a9cf32b89
mjb#bohr:~/Downloads/myaudiservice.com$ openssl rsa -noout -modulus -in myaudiservice.com.key | openssl md5
(stdin)= 36d37e4f8f8672c127178a4a9cf32b89
And they match....but I still get the:
No certificate matches private key
What can I try next?
You cannot have multiple -in arguments. It will just take the last, i.e. gd_bundle-g2-g1.crt. And no certificate in this file matches the key. Instead you should combine all certificates (and maybe even the key) into a single file and use this as argument for a single -in option.

How to add my private key to my cert file?

As per official OpenSSL documentation https://www.openssl.org/docs/man1.1.1/man1/x509.html\
-CAkey filename
Sets the CA private key to sign a certificate with. If this option is not specified then it is assumed that the CA private key is present in the CA certificate file.
I have created a cert file using a private key as below:-
openssl genrsa -des3 -out barneyCA.key 2048
openssl req -x509 -new -nodes -key barneyCA.key -sha256 -days 1825 -out rootCA.pem
After this, I try to sign a csr without mentioning -CAkey and get an error as below:-
openssl x509 -req -in barney.test.csr -CA rootCA.pem -CAcreateserial -out barney.test1.cer -days 825 -sha256 -extfile barney.text.ext
Signature ok
subject=/C=IN/ST=KA/L=BLR/O=CLDR/OU=SPRT/CN=SQDRN/emailAddress=rjindal#cloudera.com
Getting CA Private Key
unable to load CA Private Key
140344774555536:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:707:Expecting: ANY PRIVATE KEY
This is expected as my certificate rootCA.pem does not have the required private key yet.
If my understanding is correct, how do I add barneyCA.key to the rootCA.pem?

Create CSR and self-signed-certificate with pyOpenSSL

using pyOpenSSL I want to create
a key pair for self-signing
a certificate signing request (csr)
a self-signed-certificate
When I use the openSSL command line tool I used the following commands to do that:
a key pair for self-signing
openssl genrsa -out pkey.pem 2048
openssl rsa -in pkey.pem -out public-pkey.pem -outform PEM -pubout
a certificate signing request (csr)
openssl req -new -key pkey.pem -subj "/C=US/O=XXX/CN=XXX" -days 365 -out csrrequest.csr
a self-signed-certificate
openssl x509 -in csrrequest.csr -req -signkey pkey.pem -days 365 -set_serial 0x12345 -sha256 -out selfsignedcert.pem
This works! Server accepts the self-signed certificate and returns a server-signed certificate.
For pyOpenSSL I use the following code:
a key pair for self-signing
psec = crypto.PKey()
psec.generate_key(crypto.TYPE_RSA, 2048)
a certificate signing request (csr)
csrrequest = crypto.X509Req()
csrrequest.get_subject().C = "US"
csrrequest.get_subject().O = "XXX"
csrrequest.get_subject().CN = "XXX"
csrrequest.set_pubkey(psec)
a self-signed-certificate
selfsignedcert = crypto.X509()
selfsignedcert.set_serial_number(12345)
selfsignedcert.gmtime_adj_notBefore(0)
selfsignedcert.gmtime_adj_notAfter(365*24*60*60)
selfsignedcert.set_subject(csrrequest.get_subject())
selfsignedcert.set_issuer(selfsignedcert.get_subject())
selfsignedcert.set_pubkey(csrrequest.get_pubkey())
selfsignedcert.sign(psec, "sha256")
This is not working! Server does not accept the self-signed certificate. The server is not able to sign and return a server-signed certificate.
By using pyOpenSSL, however, I miss the input of openssl x509 -in csrrequest.csr -req for the creation of the self-signed certificate...
Where is my fault? Does anyone know what I am doing wrong??
Thanks!
You need to sign the CSR with the private key (similar to a self-signed certificate, but the CA will replace this signature with its own signature in the final certificate).
Try csrrequest.sign(psec,"sha256")
What is it that is not working ?
I noticed that the times are set wrong
Instead of :
selfsignedcert.gmtime_adj_notBefore(0)
selfsignedcert.gmtime_adj_notAfter(365*24*60*60)
What if you tried
current_ts = int(datetime.datetime.now().timestamp())
selfsignedcert.gmtime_adj_notBefore(current_ts)
selfsignedcert.gmtime_adj_notAfter(current_ts + 365*24*60*60)

I'd like to create SSL sertificates for my test environment

Does anyone have a handy script to generate SSL certificates such that it generates the CA certificate and the server certificate. More importantly, create it in a way that I can import the CA certificate into my trusted root list (of my windows system) so that the browser does not flag the site as untrusted.
I used the following script to do it but I am not able to persuade my browser to trust the certificate.
I'd greatly appreciate any help here.
# Generate a private key
openssl genrsa -des3 -out server.key 1024
# Generate a CSR (Certificate Signing Request)
openssl req -new -key server.key -out server.csr
# Remove Passphrase from Key
cp server.key server.key.org
openssl rsa -in server.key.org -out server.key
# Generating a Self-Signed Certificate
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Regards,
Kashyap
Your script is only generating one certificate, a self-signed certificate. Usually, the self-signed certificate is called the Root certificate. This can be used as a CA certificate, but often an intermediate CA certificate is created and signed by the Root private key. This intermediate CA certificate is then used to sign Server certificates. So you have this hierarchy:
Root -> CA -> Server
The CA and Root cert can go into the trusted certificate list. Then a browser that trusts that list will also trust any certificate signed by the CA or Root entities.
You don't have to have this hierarchy...you can use the Root certificate as the CA and skip the middle cert. You can also just use 1 self-signed certificate as the Root/Server certificate. See this article (Trusting self-signed certificates).
But assuming you do have this hierarchy, here are some OpenSSL commands to generate the necessary keys and certificates:
# 1. Create Root private key
openssl genrsa -out root.key 2048
# 2. Create self-signed Root certificate
openssl req -new -key root.key -x509 -out root.crt -days 5000 -sha256
# 3. Create CA private key
openssl genrsa -out ca.key 2048
# 4. Create CA CSR
openssl req -new -key ca.key -out ca.csr -days 5000
# 5. Sign and create CA certificate
openssl x509 -req -in ca.csr -CA root.crt -CAkey root.key -out ca.crt -set_serial 2 -days 5000 -sha256
# 6. Create Server private key
openssl genrsa -out server.key 2048
# 7. Create Server CSR
openssl req -new -key server.key -out server.csr -days 5000
# 8. Sign and create Server certificate
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -out server.crt -set_serial 3 -days 5000 -sha256
Change the key bits, # of valid days, serial numbers, and add V3 extensions as you see fit.
Also remember that different browsers have different lists that they trust. Chrome and IE use the Windows default list. Firefox has its own list.
Do you have a trusted CA certificate?
You are generating a self-signed certificate which is always considered as untrusted by browsers.

How to generate CSR for SSL that works with Nginx & Apache?

I want to generate the CSR file for requesting SSL (wildcard) certificate. This certificate and private key will be used on multiple machines with both Apache and Nginx.
RapitSSL states the following commands for the different setups:
Nginx
$ openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr
Apache Mod SSL
$ openssl genrsa -des3 -out <private key file name>.key 2048
Apache-SSL
$ openssl genrsa -des3 -out www.yourdomain-example.com.key 2048
Is there a way to generate a CSR that works with both Apache and Nginx?
Apache Mod SSL
$ openssl genrsa -des3 -out < private key file name>.key 2048
Apache-SSL
$ openssl genrsa -des3 -out www.yourdomain-example.com.key 2048
These two are obviously the exact same command, with a different way of writing the example name. They just generate the key pair, you'd need an additional req command to generate a CSR too.
genrsa generates a key pair, and req generates a CSR. However, req can perform both operations at once when using -newkey.
See OpenSSL req example documentation:
Create a private key and then generate a certificate request from it:
openssl genrsa -out key.pem 1024
openssl req -new -key key.pem -out req.pem
The same but just using req:
openssl req -newkey rsa:1024 -keyout key.pem -out req.pem
How to generate CSR for SSL that works with Nginx & Apache ...
Is there a way to generate a CSR that works with both Apache and Nginx?
A quick answer to the questions to clarify things... Nginx and Apache don't consume CSRs. They use certificates and private keys.
Perhaps you meant to say something about a self-signed certificate? If so, add the -x509 option to the openssl req command. That creates a self signed certificate rather than a signing request.
There's a lot more to self-signed certificates (and server certificates in general). See, for example, How to create a self-signed certificate with openssl?