A Public Key Based Encryption example using OpenSSL which also covers the basic key generation functions needed when making Security Certificates.

### Asymmetric Encryption

Otherwise known as Public-Key Cryptography relies on two keys. One private key which is kept secret and is used only to decode and a another publicly shared key that is used to encode all messages. Messages encoded with the public key can only be decoded quickly using the private key.

The strength of these types of cryptograohy mechanisms depend on the power of the ciphers and algorithms used in the encoding and key generation phases. The methods utilized rely on the validity of certain mathematical operations being quick to perform in one direction but being orders of magnitude slower in the reverse direction thus making it computionally infeasible to deduce the private key from the public key in a reasonable amount of time.

For example, one can think of the process as being akin to mixing two primary colours to produce a entirely new colour like in the instance of combining Yellow and Blue to produce Green. However, the reverse operation, that is to seperate Green into its constituent primary colours, is not trival. A similar math operation would be the multiplication of prime numbers to generate a hash whose result would have to reversed by factorization to deterime the two original numbers combined. This is a simple mental operation when the numbers are small but becomes exceedly difficult as the size of the numbers being multiplied increases.

```
Operation #1 needs to very quick (multiplication) i.e AxB = C
Operation #2 needs to be very slow (factoring) i.e C (D1,D2) = (A,B)
```

### OpenSSL

OpenSSL is a library and command line utility developed by the OpenSSL Project team. The toolset comes standard on most Unix and Linux systems. It is also commonly used to implement SSL/TLS on webservers which is needed for the HTTPS protocol. OpenSSL also supports many SSH, SFTP, and SCP applications.

### Generating a Secret Key

The first thing that needs to be done is to generate a secret key. This key will be used to derive our public key that will be shared freely.

In the example below openssl will use the RSA algorithm combined with the DES3 digest algorithm to generate the 2048 bit key. Our key will be protected by a passphrase (*password*) and stored in ciphered plain text in the file named *secret.key*

```
openssl genrsa -des3 -out secret.key 2048
```

### Generating a Public Key

Our public key will be created from the previously generated private key. To access the private key you will need supply the passphrase used during the generation.

```
openssl rsa -in secret.key -out public.key -outform PEM -pubout
```

### Generating a random key to be used with the symmetric cipher

With only the above public/private key pair we could go ahead and encrypt data but one problem would be that encoding large amounts of data with assymetric encryption is considerably slower compared to the alternative symmetric schemes. However, more significantly the *rsautl* option in openssl can only decode messages the size of the key minus 11 bits which is not very useful as most keys will only be 2048 bits or less.

Therefore, we have a final step to take before we can encode raw data. A random key needs to be generated for use with the faster symmetric cipher encryption method. We will pass our random key to the cipher that will do the actual encryption. AES-256-cbc algorithm will be our cipher of choice for this example as it is the currenty recommended USA government cipher of choice.

```
openssl rand -base64 128 > <random key>
```

### Encrypting data using AES cipher

To encrypt the raw data we pass the file as input to openssl using the encode option and tell it to cipher using the aes-256-cbc algorithm. Any other cipher method supported by openssl can be substitued for *aes-256-cbc*. The previoulsy generated random key will serve as the code needed to unlock the file.

```
openssl enc -aes-256-cbc -a -salt -in <raw data> -out <encrypted data> -pass file:<random key>
```

Finally the random key must be encrypted using the public key for transmission. To decode the data both the encrypted random key and encrypted data will need to be sent.

```
openssl rsautl -encrypt -inkey public.key -pubin -in <random key> -out <random encrypted>
```

### Decrypting the data

To decode, first decrypt the random key and then use the decoded random to decipher the encrypted raw data.

```
openssl rsautl -decrypt -inkey secret.key -in <random encrypted> -out <random key>
openssl enc -d -a -aes-256-cbc -in <ciphered data> -out <raw data> -pass file:<random key>
```

That's it! All done. Now go hide your secrets :)

**Note:**Remember to replace the contents of all <> with the actual file paths.

## Further Reading

Read our Securing the Connection series to see how OpenSSL is used to generate security certificates on the web. More guides like this can also be found by reviewing the Tutorial section.

Additional external encryption references are below.

An encryption example using PGP instead of OpenSSL