SSL Intermediate CA used to create and sign client certificate - ssl

So I have my self-signed root CA, which I used to create an intermediate CA, both of which look good and work fine. While trying to create and sign a client certificate I receive an error opening the private key used, but when I check things the file is there as it should be. Here are the steps that I took with this.
openssl genrsa -aes256 -out intermediate/private/controllers-ecc.key.pem 2048
chmod 400 intermediate/private/controllers-ecc.key.pem
openssl req -config intermediate/ssl_ca_devices.cnf \
-key intermediate/private/controllers-ecc.key.pem -new -sha256 \
-out intermediate/csr/controllers-ecc.csr.pem
openssl ca -config ./intermediate/ssl_ca_devices.cnf \
-extensions server_cert -days 375 -notext -md sha256 \
-in ./intermediate/csr/controllers-ecc.csr.pem \
-out ./intermediate/certs/controllers-ecc.cert.pem
That last command will spit out the following:
Using configuration from ./intermediate/ssl_ca_devices.cnf
Error opening CA private key ~/Desktop/ca/intermediate/private/ca-devices-ecc.key.pem
140602185837312:error:02001002:system library:fopen:No such file or directory:bss_file.c:406:fopen('~/Desktop/ca/intermediate/private/ca-devices-ecc.key.pem','r')
140602185837312:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:408:
unable to load CA private key
I can literally copy the string above and open the file that it errors on opening:
cat ~/Desktop/ca/intermediate/private/ca-devices-ecc.key.pem
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,CA927018408CCDD198827262EB52238A
dFa99Jgfr/ZUeJNWVWjE2lKBCfqJhJlmcqdy4U3hy6e3kkdG27JmKD1EY9uCj2OF
WJV8rat1oncASy+dIci8XT0LOoBQ9rK8nyK+bsm9M1n/5j1moNCyesAUfnjss8kE
DmfYjeJERBwVNgNNfK4dT0ejHRKt5r8PZsxWoURXkjyZ8vn3/4UHSkDTXScgHiML
Jkz7WGSNeXLR6BVgJuuFHht6283Vt8vnKq5gtQMdoEjFks7Da7EA96tEx9xUjHlC
VKGUGPoqcdfiwvfLjbsFBOhM29QBuoMDVyrEbC3cNdywDI39DZLYxCcVjzhzvQQw
Xz5R1YycR1eAS0M+qBMqUOvs/8PHlJCVRLqEJ5M/gYSeXmuKgqZPILfWr5R2vJEA
C3A9+gEWJC8RiyjxEv1gFwGEvgdChmVs30oaxPUjum3aTfVATrT071FP/V57dppw
5YgFA5SXvP15u3LQVYWDt8UOi3YU9zELoSomUZeIeYnKOnmt4CWzo0MKdwDkOrcQ
GoPRP3GB1HhRIrbtwTsBkChDLx+AbOBiI1QXEiEOEC+c0xwf6Ld/nqhpg5nQfypA
ydEjaI9NyG3whCW2LyLZr0gCFomB7CPO8vyvnxEvnJ2AETrczmbzAFmx2VLnzPE4
PWUatzm0tZXoP/8bommP0CqkWwedXhqiIitiCDIdpovynJlg+5ENa7jhFC6z57ty
WQbPkRIFMw+PZPU65hV7OfXVWMNm+rxbB3z5yDryc9lIzaZqVUKgBWjKi0JHF97X
3Fd3RA/t7jZW4oP4ZBP61woINnWZKAXK2DMWFGZ3gElgfFCmAaPr2YKWXzQmHSmS
-----END RSA PRIVATE KEY-----
So my question is whether this file is somehow mis-formatted or invalid in some way that would cause this error? Or perhaps I'm calling the file incorrectly?

... fopen:No such file or directory:bss_file.c:406:fopen('~/Desktop/ca/intermediate/private/ca-devices-ecc.key.pem','r')
The path ~/... is not the real filename but the ~ gets expanded by the shell to the users home directory. If used outside the shell (like in a configuration file) this shortcut is usually not supported, i.e. you have to specify the actual path, like /home/whoever/.... To get the full path you could use echo or similar, like
$ echo ~/tmp
/home/whoever/tmp

Related

Question about how to get openssl to work with Apache

So I need to create a self signed certificate for a web page I am making with Apache. I have looked up and followed different sets of instructions but I am missing something. I am a student and have never used ssl or apache. Apache is installed, the localhost page is up and showing the content of the html docs I've edited. OpenSSL is installed. So it's probably me missing something. I keep getting messages like this
C:\Program Files\OpenSSL-Win64\bin>openssl genrsa -des3 -out server.key 1024 genrsa: Can't
open "server.key" for writing, Permission denied
C:\Program Files\OpenSSL-Win64\bin>openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout
mysitename.key -out mysitename.crt
Generating a RSA private key
..........................+++++
...................................+++++
writing new private key to 'mysitename.key'
req: Can't open "mysitename.key" for writing, Permission denied
any suggestions?
You are missing private key creation.
1 Private key creation
openssl genrsa -out server.key 2048
result
$ cat server.key
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAr2E2AUJ+TbptdBVMxYHmUzRpOflP69SX03NyuKh75XIO4tp6
...
Fhe+gzT7QD7Dg9SdP45eQWy5jtDYu4HIcy/ha0sikBi9+8pSs6qo
-----END RSA PRIVATE KEY-----
2 Certification Signing Request creation with #1's private key
openssl req -new -key server.key -out server.csr
common needs localhost other options are default or your.
Common Name (e.g. server FQDN or YOUR name) []:localhost
result
$ cat server.csr
-----BEGIN CERTIFICATE REQUEST-----
MIICijCCAXICAQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUx
...
sDS9gxYfks/7zxvtBzOWR3ZZzjlenpyqqu4aYZyb
-----END CERTIFICATE REQUEST-----
3 Certification creation
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
result
$ cat server.crt
-----BEGIN CERTIFICATE-----
MIIDOTCCAiECFB0jWF04/GTmwfh8Ph1Zqeulb0IuMA0GCSqGSIb3DQEBCwUAMFkx
...
nrp0uU09oePMMMEn5g==
-----END CERTIFICATE-----
4 local server code by python (file name is server.py)
from http.server import HTTPServer, BaseHTTPRequestHandler
import ssl
class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.end_headers()
self.wfile.write(b'Hello, world!')
httpd = HTTPServer(('localhost', 4443), SimpleHTTPRequestHandler)
httpd.socket = ssl.wrap_socket (httpd.socket,
keyfile="./server.key",
certfile='./server.crt', server_side=True)
httpd.serve_forever()
5 local server test
python server.py

How do I generate a pfx file from PEM?

I have a bunch of .Pem files.
One is (as far as I can tell) the CACert
mycacert.pem
the other is the certificate
mycert.pem
and finally what I am led to believe is the key file which is confusingly called the same as the certificate (but for this example I will call it something different)
key.pem
How do I form a PFX file from these?
I have tried to run the following command
openssl pkey -in C:\Temp\key.pem -out C:\Temp\my.key
however I get the following error
unable to load key 2147581984:error:0909006C:PEM routines:get_name:no
start line:crypto/pem/pem_lib.c:745:Expecting: ANY PRIVATE KEY
If I open the file in notepad I see the following
-----BEGIN NEW CERTIFICATE REQUEST-----
many characters
-----END NEW CERTIFICATE REQUEST-----
Basically I just need to create a pfx from the files I have but I seem to need a *.key file, a *.crt file and another *.crt file for the CACert, non of which I have.
One more thing to note. The two certificate pem files contain multiple certificates in each.
The command you are looking for is:
openssl pkcs12 -export -in cert.pem -inkey key.pem -out pkcs12.pfx -certfile cacert.pem
Where cert.pem is your certificate, key.pem is the private key, cacert.pem is the CA certificate and pkcs12.pfx is the pkcs12 file that will be created.
The command may asks for a password to decrypt the private key and will ask for a new password to encrypt the private key inside the pkcs12.
You can find the openssl pkcs12 command documentation, here.

import keypair to an existing pkcs12 keystore under a new alias name

I am learning OAUTH2 and OpenID Connect and configuring multiply tomcat servers (a Client for the UI, and multiply Resource Servers for the APIs) to use SSL. So I have created a PKCS12 keystore with a self-signed certificate + private key the following way and then I pushed it under my 1st Tomcat:
(I know that the commands bellow can be simplify and combine into one (or two) but I deliberately keep tem separately because that way I can see and understand the steps better)
(1) The keypair was created with openssl this way:
openssl genrsa \
-des3 \
-passout pass:$phrase \
-out id_rsa_$domain.key $numbits
(2) Then I created a Certificate Signing Request with this command:
openssl req \
-new \
-key id_rsa_$domain.key \
-passin pass:$phrase \
-subj "$subj" \
-out $domain.csr
(3) After that I created a x509 certificate:
openssl x509 \
-req \
-days $days \
-in $domain.csr \
-signkey id_rsa_$domain.key \
-passin pass:$phrase \
-out $domain.crt
(4) Finnaly I have created a key-store in PKCS12 format:
pem=$domain.pem
cat id_rsa_$domain.key > $pem
cat $domain.crt >> $pem
openssl pkcs12 \
-export \
-in $pem \
-passin pass:$phrase \
-password pass:$keystore_pwd \
-name $domain \
-out example.com.pkcs12
rm $pem
At the end of this process I have the following files:
id_rsa_authserver.example.com.key: the private (and public) key
authserver.example.com.crt: the self signed certificate
example.com.pkcs12: the keystore
Inside the .pkcs12 file I only have one key-pair entry under the authserver.example.com alias. I have checked the result with KeyStore Explorer as well and everything looks fine and the 1st Tomcat works properly with that keystore.
Then I repeated the steps (1), (2) and (3) and I generated new files for order.example.com host machine and at the end I have two new files:
id_rsa_order.example.com.key
order.example.com.crt
Now I would like to add to my "root" example.com.pkcs12 keystore this new keypair + certificate under the order.example.com alias in order to I keep all certs that I use for my demo in one keystore. I can do it easily with the KeyStore Explorer tool via the tools > import key pair > openSSL > browse the private key and cert files, but this is not enough good for me. I would like to do the import via command line using OpenSSL.
Unfortunately I have not found the proper openssl command that I can use to ADD my 2nd key+cert to the existing keystore.
What is the command that I can use?

SSL Certificate For AWS Load Balancer

I first followed the instructions on AWS's documentation: http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/ssl-server-cert.html#generate-key-submit-csr
openssl genrsa -out mykey-private-key-file.pem 2048
openssl ecparam -name prime256v1 -out mykey-private-key-file.pem -genkey
openssl req -sha512 -new -key mykey-private-key-file.pem -out mykey-csr.pem
But when we tried to submit our CSR, then it complained, so then I followed the instructions on rapidssl:
https://knowledge.rapidssl.com/support/ssl-certificate-support/index?page=content&actp=CROSSLINK&id=SO13985
openssl genrsa -des3 -out mykey-private-key-file.pem 2048
openssl req -new -key mykey-private-key-file.pem -out mykey-csr.pem
openssl req -new -key mykey-private-key-file.pem -out mykey-csr.pem
We got our approval response with the x.509 Web Server Certificate and Intermediate CA.
When I copy the mykey-private-key-file.pem into the "Private Key" field on the EC2 Management Console, then it complains that:
"Error creating certificate
Unable to parse key; the body is encrypted."
I don't really know what I'm doing. I tried converting the private key like they suggest here: https://www.geekpete.com/blog/converting-ssl-pem-format-aws/ but then it doesn't match. Does this mean I have to go through the process all over again?
Since it took me a while to figure this out as well, I thought I would post my process here (in hopes that it saves someone some time).
This process assumes you already know how to request a certificate from your favorite certificate issuer.
You can just to a find-and-replace on "yourDomain" and then run the commands at a bash prompt. OSX or pretty much any flavor of Linux should do just fine.
# to generate a certificate request
openssl req -new -newkey rsa:2048 -nodes -keyout yourDomain.key -out yourDomain.csr
# Sumbit the CSR. When the CRT file comes back...
# Open the cert in a text editor...
# create a new file
vi yourDomain.crt
# press 'i' to start insert mode
# paste the contents of the CRT file you received
# prese ESC, then 'wq', then enter. This saves the file and exits VIM
# convert the CRT you just wrote to disk into the PEM format expected by ELB
openssl x509 -in yourDomain.crt -out yourDomain.pem -outform PEM
# convert the private key to PEM format expected by ELB
openssl rsa -in yourDomain.key -outform PEM -out yourDomain.pem.key
# display the contents of the private key file and certificate file so you can paste them into the dialog when setting up the listener on the ELB
cat yourDomain.pem.key
cat yourDomain.pem
Actually it was because of the copy and paste from my email. Even though I copied it into a text editor first. Totally lame error message.
But I did have to to run this step from the geekpete link.
openssl rsa -in yourwebsite_private.key -out pem-yourwebsite_private.key

How to get .pem file from .key and .crt files?

How can I create a PEM file from an SSL certificate?
These are the files that I have available:
.crt
server.csr
server.key
Your keys may already be in PEM format, but just named with .crt or .key.
If the file's content begins with -----BEGIN and you can read it in a text editor:
The file uses base64, which is readable in ASCII, not binary format. The certificate is already in PEM format. Just change the extension to .pem.
If the file is in binary:
For the server.crt, you would use
openssl x509 -inform DER -outform PEM -in server.crt -out server.crt.pem
For server.key, use openssl rsa in place of openssl x509.
The server.key is likely your private key, and the .crt file is the returned, signed, x509 certificate.
If this is for a Web server and you cannot specify loading a separate private and public key:
You may need to concatenate the two files. For this use:
cat server.crt server.key > server.includesprivatekey.pem
I would recommend naming files with "includesprivatekey" to help you manage the permissions you keep with this file.
I needed to do this for an AWS ELB. After getting beaten up by the dialog many times, finally this is what worked for me:
openssl rsa -in server.key -text > private.pem
openssl x509 -inform PEM -in server.crt > public.pem
Thanks NCZ
Edit: As #floatingrock says
With AWS, don't forget to prepend the filename with file://. So it'll look like:
aws iam upload-server-certificate --server-certificate-name blah --certificate-body file://path/to/server.crt --private-key file://path/to/private.key --path /cloudfront/static/
http://docs.aws.amazon.com/cli/latest/reference/iam/upload-server-certificate.html
A pem file contains the certificate and the private key. It depends on the format your certificate/key are in, but probably it's as simple as this:
cat server.crt server.key > server.pem
Additionally, if you don't want it to ask for a passphrase, then need to run the following command:
openssl rsa -in server.key -out server.key
this is the best option to create .pem file
openssl pkcs12 -in MyPushApp.p12 -out MyPushApp.pem -nodes -clcerts
I was trying to go from godaddy to app engine. What did the trick was using this line:
openssl req -new -newkey rsa:2048 -nodes -keyout name.unencrypted.priv.key -out name.csr
Exactly as is, but replacing name with my domain name (not that it really even mattered)
And I answered all the questions pertaining to common name / organization as www.name.com
Then I opened the csr, copied it, pasted it in go daddy, then downloaded it, unzipped it, navigated to the unzipped folder with the terminal and entered:
cat otherfilegodaddygivesyou.crt gd_bundle-g2-g1.crt > name.crt
Then I used these instructions from Trouble with Google Apps Custom Domain SSL, which were:
openssl rsa -in privateKey.key -text > private.pem
openssl x509 -inform PEM -in www_mydomain_com.crt > public.pem
exactly as is, except instead of privateKey.key I used name.unencrypted.priv.key, and instead of www_mydomain_com.crt, I used name.crt
Then I uploaded the public.pem to the admin console for the "PEM encoded X.509 certificate", and uploaded the private.pem for the "Unencrypted PEM encoded RSA private key"..
.. And that finally worked.
All of the files (*.crt, server.csr, server.key) may already be in PEM format, what to do next with these files depends on how you want to use them, or what tool is using them and in which format it requires.
I'll go a bit further here to explain what are the different formats used to store cryptography materials and how to recognise them as well as convert one to/from another.
Standards
Standards
Content format
File encoding
Possible content
X509
X
Certificates
PKCS#1
X
RSA keys (public/private)
PKCS#7
X
Certificates, CRLs
PKCS#8
X
Private keys, encrypted private keys
PKCS#12
X
Certificates, CRLs, private keys
JKS
X
Certificates, private keys
PEM
X
DER
X
Common combinations
Content \ Encoding
PEM (*)
DER (**)
Binary
X509
X
X
PKCS#1
X
X
PKCS#7 (***)
X
X
PKCS#8
X
X
PKCS#12 (***)
X
JKS (***)
X
This is a gist explains the same thing + commands for conversion/verification/inspection.
In conclusion, typical steps to work with cryptography/PKI materials:
Understand which format they are in (use verification/inspection commands)
Understand which format they are required (read doc)
Use conversion commands to convert the files
Optional: use verification/inspection commands to verify converted files
What I have observed is: if you use openssl to generate certificates, it captures both the text part and the base64 certificate part in the crt file. The strict pem format says (wiki definition) that the file should start and end with BEGIN and END.
.pem – (Privacy Enhanced Mail) Base64 encoded DER certificate,
enclosed between "-----BEGIN CERTIFICATE-----" and "-----END
CERTIFICATE-----"
So for some libraries (I encountered this in java) that expect strict pem format, the generated crt would fail the validation as an 'invalid pem format'.
Even if you copy or grep the lines with BEGIN/END CERTIFICATE, and paste it in a cert.pem file, it should work.
Here is what I do, not very clean, but works for me, basically it filters the text starting from BEGIN line:
grep -A 1000 BEGIN cert.crt > cert.pem
Trying to upload a GoDaddy certificate to AWS I failed several times, but in the end it was pretty simple. No need to convert anything to .pem. You just have to be sure to include the GoDaddy bundle certificate in the chain parameter, e.g.
aws iam upload-server-certificate
--server-certificate-name mycert
--certificate-body file://try2/40271b1b25236fd1.crt
--private-key file://server.key
--path /cloudfront/production/
--certificate-chain file://try2/gdig2_bundle.crt
And to delete your previous failed upload you can do
aws iam delete-server-certificate --server-certificate-name mypreviouscert
Download certificate from provisional portal by appleId,
Export certificate  from Key chain and  give name (Certificates.p12),
Open terminal and goto folder where you save above Certificates.p12 file,
Run below commands:
a) openssl pkcs12 -in Certificates.p12 -out CertificateName.pem -nodes,
b) openssl pkcs12 -in Certificates.p12 -out pushcert.pem -nodes -clcerts
Your .pem file ready "pushcert.pem".
Open terminal.
Go to the folder where your certificate is located.
Execute below command by replacing name with your certificate.
openssl pkcs12 -in YOUR_CERTIFICATE.p12 -out YOUR_CERTIFICATE.pem -nodes -clcerts
Hope it will work!!
On Windows, you can use the certutil tool:
certutil -encode server.crt cert.pem
certutil -encode server.key key.pem
You can combine both files to one in PowerShell like this:
Get-Content cert.pem, key.pem | Set-Content cert-and-key.pem
And in CMD like this:
copy cert.pem+key.pem cert-and-key.pem /b