How to check a public RSA key file - shell

Inside a shell script I want verify public RSA file.
All I want to do is that find a way to check this file is a genuine public key file, nothing else.
Can I ask experts here what are the ways I can verify this input file to check this is a genuine public key file , not a regular file.
I will be using this public key file in future to validate an incoming encrypt gzip file but that is out of scope for now.
All I want is validate input file to check its genuine RSA public key file not an ordinary file.please note that I do not have any other files with me (eg : private key) .
e.g.: if the file is ‘public.pem’ I just want check inside that it’s a genuine RSA public key file not just a file with texts or file is not corrupted .
I’m already checking that file is not zero sized and md5 .
other possible checks I found
check file got text ‘BEGIN PUBLIC KEY’ and ‘END PUBLIC KEY’
Also found this command in google , Is there a better way to do this using openssl
‘openssl rsa -noout -text -inform PEM -in pubkey.pem -pubin’
Thanks

It's possible to use any public key format parser, including openssl or even parse key yourself as the format is not that difficult.
Command line tools set a non-zero exit code, when parsing fails:
openssl rsa -inform PEM -pubin -in pubkey.pem -noout &> /dev/null
if [ $? != 0 ] ; then
echo "this was definitely not a RSA public key in PEM format"
exit 1
fi
Just to check any public key:
openssl pkey -inform PEM -pubin -in pubkey.pem -noout &> /dev/null
if [ $? != 0 ] ; then
echo "this was definitely not a public key in PEM format"
exit 1
fi

The following script should work for all PEM-formatted keys and certs supported by OpenSSL. I have tested it on various valid and invalid ECDSA and RSA keys with matching and non-matching certs.
Save this as verify-cert-key:
#!/usr/bin/env bash
certFile="${1}"
keyFile="${2}"
certPubKey="$(openssl x509 -noout -pubkey -in "${certFile}")"
keyPubKey="$(openssl pkey -pubout -in "${keyFile}")"
if [[ "${certPubKey}" == "${keyPubKey}" ]]
then
echo "PASS: key and cert match"
else
echo "FAIL: key and cert DO NOT match"
fi
Make it executable:
chmod +x verify-cert-key
Run it on a cert and key:
./verify-cert-key server-crt.pem server-key.pem

Try this command if your public key starts with -----BEGIN RSA PUBLIC KEY-----
openssl rsa -RSAPublicKey_in -in /path/to/pub_key.pem -noout -text

Related

Shell-script to decrypt file

I have to create a shell-script that can decrypt a RSA key file that is encrypted with a specific .pem file. And then to decrypt zip file with the AES key which I get from the RSA file once it is decrypted in a file named keyaes (or whatever you want).
Here are the two commands I have to use
openssl rsautl -decrypt -in AES_KEY -inkey CERTIFICATE.pem -out keyaes
openssl enc -d -aes-256-cbc -in zipfile.zip -out extraction.zip -nosalt -p -K RSA_KEY_from_key_aes_output -iv 0
The commands work perfectly, the problem is in my script I don't know how to make it automatically and to get the key from the keyaes output and put it into the next command properly.
How can I do it ?
you could just use bash command substitution in the second command, using backticks
openssl enc -d -aes-256-cbc -in zipfile.zip -out extraction.zip -nosalt -p -K `cat output_filename_with_aes_key` -iv 0

How to handle information of certificate in a PEM file

I exported certificates from keychain to a PEM file. I want to handle information of each certificate in a loop by writing a shell-script file.
When I run this command to check the file:
openssl crl2pkcs7 -nocrl -certfile [file name here].pem | openssl pkcs7 -print_certs -text | grep -E '(Subject:|Not After)'
All certificates's information will be printed. But when I run this command:
openssl x509 -in certs.pem -text
It only shows information of the first certificate in the file. I tried to get count of certificate in the PEM file with a shell, it returned 1.
#! /bin/bash
i=0;
for cert in [PEM file path]; do
let "t=$i + 1";
echo $t;
done
Could anyone help me to handle certificates in PEM file?. Thank you so much.
Usually the certificates are separated by the BEGIN/END-comments. You could split the PEM-string like this:
IN="-----BEGIN CERTIFICATE-----..."
CERTS=( $(IFS="-----BEGIN CERTIFICATE-----" echo "$IN") )
echo ${CERTS[0]}
echo ${CERTS[1]}
...

Verify SSL certificate against various CRL files

I am given multiple certificate files e.g. "cert1.crt", "cert2.crt" etc, and multiple CRL lists, "list1.crl", "list2.crl" etc. No rootCA or any other type of files are provided. My task is to find out what certificates have NOT been revoked. Despite extensive search for "verification" command I failed to find any command or procedure that would provide me at least a clue. In the end, I managed to do some bash script aerobatics which let me manually test serial number for each .crt file
for((i=1;i<9;i++))
do
echo $i
fileIn="crl"$i".crl"
#serial is manually c/p from each .crt file
serial="1319447396"
OUTPUT="$(openssl crl -in $fileIn -noout -text | grep $serial)"
echo $OUTPUT
done
This way I could do it manually one at a time, but it will work only for small number of files (9 at present). With tens of files it would get tiresome and ineffective, with 100+ it would get impossible to do it like this.
I was wondering is there a "smart" way to validate .crt against .crl? Or at least is there a way to bash script the job so I wouldn't have to check each .crt manually? Right now it's way beyond my scripting knowledge.
So, in pseudo, I would be thrilled if something like this existed:
openssl x509 -verify cert1.cert -crl_list list8.crl
In general, yes, each certificate is checked against a CRL, as is detailed in this guide.
But, Actually, each crl is a simple list of revoked certificate serial numbers.
The list contained in a crl could be expanded with:
openssl crl -inform DER -text -noout -in mycrl.crl
Asuming the crl is in DER form (adapt as needed).
Expand each (all) crl to a text file, like:
openssl crl -inform DER -text -noout -in mycrl.crl > mycrl.crl.txt
The out file could be reduced to only the Serial Number: lines.
Get the Serial Number from the text expansion of a cert:
mycrt=$(openssl x509 -in mycrt.com.crt -serial -noout)
mycrt=${mycrt#*=}
grep the serial number in all text files from step one (if one match the cert is revoked) in one call to grep:
if grep -rl "$mycrt" *.crl.txt 2>/dev/null; then
echo "the certificate has been revoked"
fi
Full script:
#!/bin/bash
# Create (if they don't exist) files for all the crl given.
for crl in *.crl; do
if [[ ! -e "$crl.txt" ]]; then
openssl crl -inform DER -text -noout -in "$crl" |
awk -F ': ' '/Serial Number:/{print $2}'> "$crl.txt"
fi
done
# Process all certificates
for crt in *.crt; do
mycrt=$(openssl x509 -in "$crt" -serial -noout)
mycrt=${mycrt#*=}
if grep -rl "$mycrt" *.crl.txt; then
echo "Certificate $crt has been revoked"
fi
done
I finally managed to solve this in a way that's maybe not optimal, but requires much less bash knowledge. Here is my script:
#!/bin/bash
for((j=1;j<10;j++))
do
indicator=0
cert="cert"$j".crt"
for((i=1;i<9;i++))
do
infile="crl"$i".crl"
SERIAL="$(openssl x509 -noout -text -in $cert | grep Serial | cut -d 'x' -f 2 | cut -d ')' -f 1)"
OUTPUT="$(openssl crl -inform DER -in $infile -noout -text | grep $SERIAL )"
if [ -n $OUTPUT ]
then ((indicator++))
fi
done
echo $cert
if [ $indicator == 0 ]
then echo "not revoked"
else
echo "revoked"
fi
done

Read common name from .pem file

is there a way to read the common name from a .pem file in my shell?
Thanks
First off, the .pem extension only refers to the type of encoding used in the file.
The common name would be a feature of the Subject or Issuer of a certificate, and can be recognised by the lines
$ grep CERTIFICATE f.pem
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
and lots of base64 encoded text in between.
If the .pem file contains an x509 certificate,
this should do the trick:
openssl x509 -in cacert.pem -noout -text
This will dump the whole certificate. The openssl x509
command has several options to suppress the fields you don't want to see. You find those explained in the man page, under TEXT OPTIONS
You can also choose to get shown just the 'Subject' of the certificate:
openssl x509 -in cacert.pem -noout -subject
Example:
Let's capture the certificate of stackoverflow.com straight from the server
$ : | openssl s_client -connect stackoverflow.com:443 > f.pem 2>& 1 &&
openssl x509 -in f.pem -noout -subject 2>& 1
Outputs:
Subject: CN = *.stackexchange.com

Working with openssl to extract information from a pkcs12 certificate

I would like some help with the openssl command. I need to automate the retrieval of the subject= line in a pkcs12 certificate for a script I'm working on.
I've used openssl to view the contents of the Identity/Certificate:
openssl pkcs12 -info -in /Users/[user]/Desktop/ID.pfx
But I am prompted three times for the password. I used -passin to eliminate one of the password prompts, but I am still being prompted for the PEM pass phrase and verification entry.
I need to figure out a way to pass ${password} to the other two password challenges or have the scrip issue a ctl-c. The piece of info I need is outputted to the stdout before the second password prompt.
Any help would be appreciated!
Obviously I gutted the certificate output for this post.... but you should get the idea of what I'm seeing:
bash-3.2# openssl pkcs12 -info -in /Users/[user]/Desktop/ID.pfx -passin pass:${password}
MAC Iteration 2048
MAC verified OK
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Certificate bag
Bag Attributes
localKeyID: ****
friendlyName: ****
subject=****
issuer=****
-----BEGIN CERTIFICATE-----
::HASH REMOVED::
-----END CERTIFICATE-----
PKCS7 Data
Shrouded Keybag: ****
Bag Attributes
localKeyID: ****
friendlyName: ****
Key Attributes: <No Attributes>
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info:
::HASH REMOVED::
-----END RSA PRIVATE KEY-----
bash-3.2#
Try this:
$ openssl pkcs12 -in ~/cert.p12 -nodes \
-passin pass:"my password" | openssl x509 -noout -subject
Or this for the common name (ruby to strip trailing whitespace):
$ openssl pkcs12 -in ~/cert.p12 -nodes \
-passin pass:"my password" | openssl x509 -noout -subject \
| awk -F'[=/]' '{print $6}'`.strip`
Copying answer here in order to remove this question from the "Unanswered" filter:
openssl pkcs12 -nokeys -in /Users/[User]/Desktop/ID.pfx -passin pass:${password}
You could also use -passin and -passout which would not prompt you again for manual input. Here is a sample code:
openssl pkcs12 -in seldpush_dev.p12 -passin pass:$password -passout pass:$password | \
sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | \
openssl x509 -subject -noout
Basically, use -keyword to fetch that value. In your case, -subject.
This is a few years late; I'm not familiar with openssl, & etc; but since I see no reference to "-nokeys" I'll give what works for me.
echo -e "$password\n$passphrase\n$passphrase\n" \
| openssl pkcs12 -in /Users/[user]/Desktop/ID.pfx -passin stdin -passout stdin
from manpage
stdin read the password from standard input.

Resources