Are you curious about the secure world of cryptography? Look no further! I would like to write this blog post to show you this awesome side of Information Security. To demonstrate the basic concepts, I will be giving a short and brief look at a well known and trusted cryptography library and toolkit called OpenSSL [1]. At my current job, I use this library just about every day.

First and foremost, what is cryptography? In my mind, it's basically a practice and study of keeping your stuff safe. In the dictionary, to give the best explanation..

But what is "encrypting" data and what is "decrypting" data? Here is a good definition I found.

To make things simple, let's say you have a picture. This picture is unencrypted right now. We call this unencrypted picture "plaintext". You can use encryption to turn this beautiful plaintext picture into unreadable gibberish. In proper terms, this "gibberish" is called ciphertext. You can then decrypt the ciphertext to view the picture in its original plaintext format!

So in short, OpenSSL, this crypto library and toolkit, can help you keep your stuff safe! In this blog post, I will be showing you the basics of crpytography - from encrypting and decrypting data to generating keys!

For this blog post, I will be using OpenSSL version 1.1.1d (10 Sep 2019). To download OpenSSL, please see this page [5] or this page [6]. If you're using a package manager such as yum, apt or brew, you should be able to search for it and install it that way. Note that for commands in the terminal, I will be using the dollar sign "$".

`$ openssl rand -out testkey.bin 32 `

(rand = generates randomness. Also, 32 is in bytes, 8*32=256)

I recommend encrypting this key (called wrapping) with a password or another key. I will go over this later on. I will also go over the "rand" parameter later. But in short, a key is just a piece of information. It it best practice to generate keys truly randomly and contain that sufficient entropy. We are using our computer's CPU to generate randomness in this case, which*technically* is not as good as a true random number generator . It’s still cryptographically secure. But I'll go over that later on.

In short, we generated entropy using our computer's CPU to make the key!

Now that we have the key, how do use it to encrypt? This is where the Symmetric-key Algorithms come into play! These algorithms (also called ciphers) are mathematical functions that work along side with the key to "mix" and "transform" the plaintext data into ciphertext.

Here are some good and approved ciphers to be used for symmetric encryption.

-AES (Rijndael)

-Blowfish

-Serpent

-Chacha20

AES, or Advanced Encryption Standard is the most used, as it has passed many tests by government and scientific organizations. We will be talking about AES in this blog post. More information about AES can be found here [7].

Lets now use the AES cipher to encrypt with a 256-bit key!

First, lets generate a random Initialization Vector (IV) - I'll talk about this later on.

`$ openssl rand -hex 16`

The output should be a 16 byte string like so: 021afbb5928ac15fa4503d90959ed139

Note: You will need this IV when encrypting and decrypting (which actually depends on the cipher). You should always use unique IVs every time you encrypt and they should be random.

`$ openssl enc -aes-256-cfb8 -in supersecret.docx -k file:testkey.bin -out encrypted -pbkdf2 -iv 021afbb5928ac15fa4503d90959ed139 `

I will now talk a little about this command.

Tells openssl to encrypt

As you may know, AES is the cipher, but what is cfb8? This is the cipher mode of operation. Not to get to technical, but the mode describes how to repeatedly apply a cipher's single-block operation to securely transform amounts of data larger than a block [8]. In short, the mode defines how the cipher encrypts and decrypts it. You can use another cipher here if you wish. Some other modes for example are CBC, CFB, OFB, and GCM. More information about modes of operation, I recommend taking a look here [9].

The plaintext document to be encrypted

Specifies the key file

Defines that the output be called encrypted, which is the encrypted plaintext document in ciphertext

This applies a pseudorandom function along with a salt value and repeats the process many times to produce a derived key be used in the operation. Let's just say it reduces vulnerabilities to brute force attacks. [10]

To hide patterns in encrypted data, you should use an IV, which introduces more randomness to the operation. Like I noted before, you should always use unique IVs every time you encrypt and they should be random. The IV should be in hexadecimal format in this case. You should remember this value as you will use it to encrypt and decrypt. More about IVs can be found here [11].

In addition, let's say you don't want to use a key file and want to use a password instead to encrypt/decrypt. You can use this command. It will prompt you for a password. The password will act as the key in this case.

```
$ openssl enc -aes-256-cfb8 -in supersecret.docx -out encrypted -pbkdf2 -iv 021afbb5928ac15fa4503d90959ed139
```

`$ openssl enc -d -aes-256-cfb8 -in encrypted -k file:testkey.bin -out supersecret-decrypted.docx -pbkdf2 -iv 021afbb5928ac15fa4503d90959ed139`

The command is very similar to the above, but it uses the "-d" parameter to decrypt and the "-in" parameter defines the ciphertext and the "-out" defines where the decrypted plaintext should be called. Note that you should use the same key and IV. You can decrypt only with the same parameters you defined when encrypting.

If your symmetric key is a password - here is how to decrypt the file...

```
$ openssl enc -d -aes-256-cfb8 -in encrypted -out supersecret-decrypted.docx -pbkdf2 -iv 021afbb5928ac15fa4503d90959ed139
```

In conclusion, using the OpenSSL command line for symmetric encryption is a great way to learn to about it. However, for general purpose encryption, I recommenced using GnuPG. Here is a brief overview of GPG for symmetric encryption.

To encrypt a document, you just have to issue this command. It should prompt you for a password. This will be the key to encrypt and decrypt. This encrypt a file called file.docx.

`$ gpg --verbose -c file.docx`

Make sure that it uses AES256 as the cipher, update the software if it doesn't. It should write the ciphertext to file.docx.gpg

To decrypt...

`$ gpg --verbose -d file.docx.gpg > file-decrypted.docx `

You cannot use keyfiles with GnuPG as far as I'm aware.

My favorite, and another great tool to use for symmetric encryption is Veracrypt [13]. With Veracrypt, you can encrypt entire hard drives if you wish. You can also just create containers on your hard drive to place your documents to be encrypted. Veracrypt is great if you like GUIs and just want to encrypt/decrypt your stuff. You can use keyfiles or passwords as keys with Veracrypt.

I highly recommend using Veracrypt or GnuPG for your day-to-day symmetric encrypting/decrypting needs. The OpenSSL command line is just a cool way to test and to see how encryption/decryption works. When you get more advanced, you can use crypto libraries such as OpenSSL (we were using its command line, not its library) and Wolfcrypt to do encryption operations. The purpose of the blog is to learn basics, maybe I'll cover the more advanced ways later. Generating keys using Openssl's command line is fine (better to use a TRNG in an HSM but I will talk about this later), just encryption and decryption can be considered not best practice.

Never expose your Private Key!

Here is a good Youtube video on Asymmetric. It can be tricky to understand at first.

https://www.youtube.com/watch?v=AQDCe585Lnc

Since we now understand some basics about Asymmetric encryption, what are the ciphers(algorithms) called? For symmetric encryption, we used AES. We cannot use AES for asymmetric encryption. These are some of the asymmetric ciphers.

-RSA

-EC (Ecliptic Curve)

There's a ton of cool math involved with these ciphers. I highly recommend you take a look each of these ciphers! I won't go into the math behind it in this blog post. When it comes asymmetric encryption, the most you can encrypt is based on the size of the key you created. For example, an RSA4096 public key can encrypt more than a RSA2048 public key. If your key size is 2048 bits, you can only encrypt files less than 2048 bits.

Furthermore, asymmetric encryption/decryption operations are very slow.

Now you may ask - "Why do so many people use Asymmetric encryption even though you can only encrypt such as small size of data? It's also so slow encrypt/decrypt!" The answer is that asymmetric encryption is usually used to encrypt a Symmetric key, which is usually 128 or 256 bits large.

Here's what they do!

Mr Lahey creates a private and public key.

Since Randy wants to send recipe.docx to Mr Lahey, Mr Lahey sends Randy his public (encryption) key. In its transit on the network, Sam Losco on the other end steals Lahey's public key! However, this is useless, as the public key can only used for encryption.

On Randy’s PC…

1) Randy creates a symmetric key (symkey.bin) and encrypts recipe.docx.

* The newly encrypted recipe.docx file will be called recipe.docx.enc

2) Randy then encrypts the Symmetric Key with Mr. Lahey's Public Key.

* The newly encrypted symmetric key is called symkey.bin.enc

Randy now sends the encrypted files (recipe.docx.enc and symkey.bin.enc) to Mr. Lahey. In transit on the network, Sam Losco steals the files! However, they are encrypted and useless, as he doesn’t have the Private (decryption) Key! He trashes the encrypted files and goes back to cooking hot dogs.

Mr.Lahey then decrypts the symmetric key (symkey.bin.enc) with his private key! With the symmetric key, he decrypts recipe.docx.enc to the original recipe.docx! They now both have a shared secret (the symmetric key). They can now talk securely to each other! What I just described to you is *kind* of how HTTPS works!

Now let's do some examples with OpenSSL! Again, generating keys using Openssl's command line is fine (better to use TRNG but I will talk about this later), just encryption and decryption operations can be considered not best practice with the OpenSSL command line tool. Another thing, we will creating these private keys in the PKCS#8 format to keep things simple [16].

This command creates a private key using RSA and a key size of 2048 bits. You can also use a key size of 4096. The private key in this case is called "privatekey.pem". KEEP THE PRIVATE KEY SAFE!

```
$ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out privatekey.pem
```

You can also encrypt (wrap) the private key with a password using AES. Just specify -aes256 like so...

```
$ openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out privatekey.pem -aes256
```

Here is how you can look at the actual details of the private key. It will show the various prime numbers and exponents that it is using. More information about this can be found here, see the "Example" section [15]. The private key in this case is called "privatekey.pem".

```
$ openssl pkey -in privatekey.pem -text
```

Here’s the command to create a public key from a private- just make sure to specify the correct private key (privatekey.pem) and specify a different name for the public key like so...

```
$ openssl pkey -in privatekey.pem -out publickey.pem -pubout
```

You can then view the details on the Public key with this command.

`$ openssl pkey -in publickey.pem -pubin -text `

Let's say we want to encrypt a file called test.txt.

Remember: the file in question, in this case, test.txt, must be less than the size of the key. If your key is RSA2048, then test.txt would have to be less than 2048 bits.

This is how to encrypt with our public key called "publickey.pem"

`$ openssl rsautl -encrypt -inkey publickey.pem -pubin -in test.txt -out test.txt.enc `

The only way you can decrypt this file (test.txt.enc) is with the private key!

Here's how to decrypt test.txt with the RSA private key (privatekey.pem)

`$ openssl rsautl -decrypt -inkey privatekey.pem -in test.txt.enc -out test-decrypted.txt `

Now that's how you do this in OpenSSL! Remember, for the most part, generating the keys using openssl is fine, and to be honest, encrypting and decrypting is fine. It's just not best practice to encrypt/decrypt with the Openssl command line. GnuPG is another way of using asymmetric encryption. There are cool tutorials out there such as this one [17] and this one [18].

As you may remember, I pointed out that with the command to create a 256-bit key, we used our PC’s CPU’s to generate entropy to produce the random numbers that is used as the key. When we are issuing this command, OpenSSL in the back-end is using a pseudorandom number generator (PRNG) [19]. These PRNGs are just algorithms that are technically not random. However, it is still considered cryptograpically secure.

`$ openssl rand -out testkey.bin 32`

I noted that this way is not technically the best way to produce randomness. The best way is with a True Random Number Generator (TRNG). A true random number generator is a piece of hardware that produces true randomness. More can be found here [20].

Anyways, here are some commands to produce randomness.

Generate 100 bytes of random data and write to a file called file.txt

`$ openssl rand -out file.txt 100 `

Generate 100 bytes of random data in hexadecimal

`$ openssl rand -hex 100 `

Generate 100 bytes of random data in base64.

`$ openssl rand -base64 100`

If you have an HSM or TRNG, you can specify it to generate true randomness.

`$ openssl rand -engine HSMexample 100`

Another cool thing OpenSSL can do is generate prime numbers! I talk about this in my older blog post, here [21]. In short, here is the command to generate a random 4096-bit prime number.

`$ openssl prime -generate -bits 4096`

Lastly, you can use OpenSSL to test and compare cipher speeds on your PC! This is a basically benchmarking test.

This tests all supported ciphers.

`$ openssl speed `

This tests a single cipher (aes-256-gcm)

`$ openssl speed evp aes-256-gcm`

In conclusion, I hope that this blog post was a good introduction to cryptography. We used OpenSSL to demonstrate basic concepts such as encryption, decryption and ciphers. Next, in part 2, I will be talking about PKI (Public Key Infrastructure)!

Any questions, concerns? Please contact me –

Blog by : Chris

[2] https://www.ahdictionary.com/word/search.html?q=cryptography+

[3] https://www.techopedia.com/definition/5507/encryption

[4] https://nvlpubs.nist.gov/nistpubs/specialpublications/nist.sp.800-57pt1r4.pdf

[5] https://www.openssl.org/source/

[6] https://wiki.openssl.org/index.php/Binaries

[7] https://en.wikipedia.org/wiki/Advanced_Encryption_Standard

[8] https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation

[9] https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf

[10] https://en.wikipedia.org/wiki/PBKDF2

[11] https://en.wikipedia.org/wiki/Initialization_vector

[12] https://www.gnupg.org/download/index.html

[13] https://www.veracrypt.fr/en/Downloads.html

[14] https://en.wikipedia.org/wiki/Public-key_cryptography

[15] https://en.wikipedia.org/wiki/RSA_(cryptosystem)

[16] https://en.wikipedia.org/wiki/PKCS_8

[17] https://www.digitalocean.com/community/tutorials/how-to-use-gpg-to-encrypt-and-sign-messages

[18] https://www.devdungeon.com/content/gpg-tutorial

[19] https://en.wikipedia.org/wiki/Pseudorandom_number_generator

[20] https://en.wikipedia.org/wiki/Hardware_random_number_generator

[21] https://memeoutpost.org/blog/03112020.html