I’ve always wanted to remember all the parameters that a command is actually using, however, my memory is not as good as it used to be. So, I need some cheatsheets from time to time.
Maybe you can benefit from this Cheatsheet if you are reading this.
According to https://openssl.org, “OpenSSL is a robust, commercial-grade, and full-featured toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. It is also a general-purpose cryptography library…”. It is licensed as some kind of Apache license. So, yes, basically it is free to use.
Working with Keys
The first thing we can do with OpenSSL is creating a new Private Key. In the example case, we are creating a key named test.private.key 4096 bit long. We can use another lengths (2048, 1024). The “more bits” used in the key generation, the stronger the cypher. 2048 is a good length for security.
# Create a new PRIVATE key openssl genrsa -out test.private.key 4096
We might also need to create a public key to be distributed. It is quite difficult to find out a private key from a public key (it would take even years of computation), however, it is very simple to get the public key from the private key:
# Get the PUBLIC key from the private key. openssl rsa -pubout -in test.private.key -out test.public.key
Both, private and public keys should have the same modulus. (You take a look to this post if you want to know why):
# Public key and Private Key need to have same modulus value to be a Key Pair openssl rsa -noout -modulus -in test.private.key openssl rsa -noout -modulus -pubin -in test.public.key
If the modulus are different, then the keys doesn’t match one with the other. Thus, what we cipher with the public key can’t be deciphered with the private one. Of course, “public key” means that we can give that key to anyone as something public so anyone can send messages ciphered messages to us. And “private key” means that it is private and none should know the content, we must keep in absolute secret our private keys.
Encrypt and Decrypt files
We won’t be able to encrypt large files using our public key. Let’s say that using a 4096 bit key we can only cipher up to roughly 500 bytes. Obviously it is not enough. And what’s more important, this cipher is really slow. However, we could use this to cipher some data:
# Encrypt with public key openssl rsautl -encrypt -inkey test.public.key -pubin -in small_file -out small_encrypted_file.dat # Decrypt with private key openssl rsautl --decrypt -inkey test.private.key -in small_encrypted_file.dat -out new_small_file.txt
# Encrypt with "private key" or sign the file: openssl rsautl -encrypt -inkey test.private.key -sign -in small_file -out small_signed_file.dat # Decrypt with "public key" or verify a signed file: openssl rsautl -verify -inkey test.public.key -pubin -in small_signed_file.dat -out new_verified_small_file
However, we can encrypt a file as large as we want just by using symmetric cryptography, using a password shared between 2 endpoints. so the message can only be read by those who have the the password to decrypt it:
# Encrypt a file: openssl enc -aes-256-cbc -salt -in file.xxx -out file.xxx.encripted # Decrypt the file openssl enc -aes-256-cbc -d -in file.xxx.encripted -out new_file.xxx
Digests (Hash algorithms)
This is the way to get hashes for file, so they can be verified by the recipients of the files.
# Digest example Using SHA-512 algorithm openssl dgst -sha512 file.xxx # To get the list of all digests available: openssl dgst -list --digest-comands
In order to see if a file has been modified, we could get a digest of the file and sign it (encrypt it with the private key):
openssl dgst -sha256 -sign test.private.key file.xxx > file.xxx.sign
We van verify the signature of the file if we have the public key:
openssl dgst -sha256 -verify test.public.key -signature file.xxx.sign file.xxx
We can get back the original information encoded in file.xxx.sign using the command shown above when I talked about Decrypt with public key:
openssl rsautl -verify -inkey test.public.key -pubin -in file.xxx.sign -out simply_as_curiosity_file
The sha256 sum will be in the “simply_as_curiosity_file” file in a binary format. We can see it using hd (hex dump) command:
So, if we’ve been able to decrypt the signature file using a public key, it must be true that it has been encrypted using the private key that only is installed in one place of for a single user.
To create a new certificate we need a Certificate request first using our private key, we can run a command like the next one:
openssl req -new -sha256 -key test.private.key -subj "/C=ES/ST=Salamanca/L=Corporario/O=Test OpenSSL S.L./OU=IT department/CN=test.example.com" -out test.example.com.csr
Of course, the modulus in our certificate must be the same than in our public and in our private keys.
openssl req -noout -modulus -in test.example.com.csr
For the verification of the certificate request, we can run:
openssl req -text -noout -verify -in test.example.com.csr
We can also create a Certificate Request and generate a private key for that certificate in the same command:
# This generates a certifcate request (test.example.com..csr) and a new private key (2.test.private.key) # Last parameter -nodes means that there will be no password for the private key. openssl req -newkey rsa:4096 -subj "/C=ES/ST=Salamanca/L=Corporario/O=Test OpenSSL S.L./OU=IT department/CN=test.example.com" \ -out test.example.com.csr -keyout 2.test.private.key -nodes
Using this certificate request and the public key, we can ask to a certification authority to provide us a singed certificate (previous payments, of course). Or, we can create a self signed certificate which could be useful in companies or in projects where we could locally trust the certificate recently done. In order to create a self signed certificate, we could do:
openssl x509 -signkey test.private.key -in test.example.com.csr -req -days 365 -out test.domain.crt
We can see the information in the certificate with these commands:
# Check Modulus. It must be the same as in private key and public key openssl x509 -modulus -noout -in test.domain.crt # Show certificate info. openssl x509 -noout -text -in test.domain.crt
In order to verify the certificate we can use this command, though it will fail because it is a self-signed certificate and possibly an untrusted one.
openssl verify test.domain.crt
We can verify a certificate installed in a Web Site this way:
openssl s_client --connect jicg.eu:443 # Or even we can extract it: openssl s_client --connect jicg.eu:443 | sed -n '/----BEGIN CERTIFICATE/, /----END CERTIFICATE/p' 2>/dev/null
Generate Random Numbers
We can also generate random numbers with Openssl this way:
# Example a 30 digit number base64 encoded openssl rand -base64 30
We can even manage to generate quite secure passwords using a command like the next one.
openssl rand 4096 | tr -cd '[:alnum:];:!@$#%=,.-_' | head -c 16 ; echo
2 Replies to “OpenSSL cheatsheet”
The Generate Random Number example is incorrect:
The parameter passed to rand is the number of bytes not the number of digits.
The tr filtering does not work unless you previously set LC_CTYPE=C
I’d recommend you installing Linux XD — Because indeed you are right when using MacOS.
Thank you for pointing out LC_TYPE=C in MacOS in order to avoid Unicode in the Terminal.