Encryption HW

Notes

  1. You should work individually
  2. You should submit all files in a single zip file.
  3. The zip archive containing both the public key and large file that you will encrypt Archive.

Project 6: Encryption

In this project, we will execute some of the security operations discussed in class using openssl.

Task 1: Encryption using different ciphers and modes

In this task, we will play with various encryption algorithms and modes. You can use the following openssl enc command to encrypt/decrypt a file.

% openssl enc <ciphertype> -e  -in plain.txt -out cipher.bin \
              -K  00112233445566778899aabbccddeeff \
              -iv 0102030405060708

(The backslashes denote the fact that the command carries over onto the next line, and are of course not necessary in general.)

Replace the <ciphertype> with a specific cipher type, such as -aes-128-cbc (for AES with 128- bit keys in CBC mode), -aes-128-cfb (cipher feedback mode), -bf-cbc (Blowfish in CBC mode), etc. You can see the list of supported ciphers on your machine by running the command openssl enc --help (note that the enc command actually does not support the --help option-—get used to the documentation for OpenSSL being rather poor—-but that it will nonetheless show you its various options and supported ciphers).

However, you will very rarely be typing in the key and initialization vector yourself: that is very prone to error, and is kind of a waste of time. Instead, we can use OpenSSL itself to help us generate random symmetric keys. Really, all we want from a symmetric key is that it be the right size and that it be random, so we generate them with OpenSSL’s rand command:

% openssl rand -base64 16 > symm_key

This will generate a 16 byte (128 bit) random value in base 64 encoding. We can use this to encrypt as follows:

% openssl enc ciphertype -e -in plain.txt -out cipher.bin \
   -pass file:symm_key -salt

Note that the key we generated, symm key, is being used instead of specifying the key by hand. Strictly speaking, we will not use this as our key, but rather as a sort of “password” that will be used to help generate the key. To see this, you can attach the -P option to view the key that is actually being used. In any event, decryption also uses the same -pass file:symm_key argument (it does not need the -salt argument — technically, neither does encryption, as it is the default, but this is just to reinforce that you should never use no salt).

Submission: Please submit two files: the first should be task1.key which is a random key value as described above, and the second should be called task1.bin. We should be able to decrypt, using 256-bit AES in CBC mode, task1.bin using task1.key as the key file (as above) to get the plaintext file: a file consisting of your UVA computing ID.

Task 2: Public Key Encryption

Task 2.1 Public key generation

Our next few tasks will make use of public/private key pairs. First, you will be generating your own key pairs and sending us your public key. As always, remember to keep your private key private!

There are a few ways to generate key pairs; many of you are probably familiar with ssh-keygen, which is commonly used to generate key pairs .ssh/id rsa and .ssh/id rsa.pub to facilitate log- ging into an SSH server (Google for more info, if you are not already familiar with this and would like to not have to enter your passwords so often when logging into a server from a machine you trust). But here, we will gain some familiarity with OpenSSL’s key generation scheme.

Your task is to generate an RSA key pair. This is done in two phases in OpenSSL; first you generate your private key, as follows:

% openssl genrsa -aes128 -out private_key.pem 1024

A couple things to note here about this input:

  • genrsa: As you’ve come to see by now, OpenSSL’s command line tool takes a command as a first argument (dgst, genrsa, and later we will see rsautl). There are often multiple ways to do the same thing, so it is best to get to know whichever way is most reliable and least prone to error (you will investigate two ways to sign later).
  • -out: private key.pem: Ultimately, the goal of the above command is to generate a private key. This argument specifies the name of the file to save it to. I’ve given this a .pem file extension to denote the fact that OpenSSL defaults to the PEM file format when working with public and private keys. (The name comes from Privacy Enhanced eMail, but the only thing that stuck from that system was the file format, so nobody ever calls it anything but PEM.)
  • -aes128: This option informs OpenSSL not to store your private key in plaintext, but rather to first encrypt it with 128-bit AES before writing it to disk. A natural question to ask is: but what the heck is the key, and won’t I need to store that key, and a key to encrypt that key, and a key to encrypt that key, and… After you run the command, you’ll notice that it asks you for a pass phrase. OpenSSL uses “password-based encryption,” using your password as input to determine an AES key. What this means is that every time you use your private key, you must be able to provide your password so that OpenSSL can decrypt the part of your private key.pem that contains the private key. Of course, as with the dgst command, you get many options here for encrypting (if you Google for examples, you will see that des3 is a common option, despite 3DES’s shortcomings).
  • 1024: Finally, we provide our desired key size. I’ve generated a 1024-bit key, but you will be generating a 2048-bit key.

Now that we have our private key, we can generate the corresponding public key:

% openssl rsa -in private_key.pem -out public_key.pem -pubout

Note that this is using the rsa command as opposed to the genrsa command we used to generate our private key in the first place. Also, since we encrypted the private key, we should expect this command to ask us for our pass phrase.

Most of the arguments are pretty straightforward. -in denotes the input file: our private key, while -out denotes the output file: our public key. The -pubout option makes explicit that we will be generating a public key as our output.

Submission: Submit a 2048-bit RSA public key in PEM format called task2.pem

Task 2.2 Public key encryption/decryption

Public key encryption and decryption in OpenSSL make use of the rsautl command. First, encryption:

% openssl rsautl -encrypt -inkey public_key.pem -pubin \
   -in plaintext -out ciphertext

Recall that public key encryption is performed with the public key (so that only the holder of the private key can decrypt the message). This is captured by the fact that we provided the public key to the -inkey option, and included the -pubin option to inform OpenSSL that that file should be interpreted as a public key.

Decryption works similarly:

% openssl rsautl -decrypt -inkey private_key.pem -in ciphertext

This will output the plaintext to stdout. Again, because we are using the private key that we encrypted with password based encryption, we will be asked for our pass phrase to complete the above command.

The problem with public key encryption. Recall that public key encryption can only operate over inputs the same size as its key, so if we use the above commands, the plaintext (and ciphertext) are both limited to the size of the key (2048 bits from Task 5.1). Of course, some times you will have to send files larger than the RSA key size: for this very task, in fact! The general approach to this is to:

  1. Generate a random symmetric key. (As in Task 1, using the openssl rand command.)
  2. Encrypt the large file with this symmetric key (as in the previous tasks).
  3. Encrypt the symmetric key with the public key, and then immediately delete the symmetric key (the sender does not need it in plaintext anymore). Encryption follows the same as in Task 5.1.
  4. Send the encrypted file and the encrypted symmetric key.

The recipient can use his or her private key to decrypt the symmetric key (using openssl rsautl -decrypt ...), and then use that to decrypt the file.

Submission: We have provided you with our own public key, public_key.pem, and a file, largefile.txt, that is too large to be encrypted using our public key alone. Encrypt largefile.txt using the method described above, and submit two files: the encrypted symmetric key task2_2_sym_key.enc and the encrypted file itself, task2_2.enc. We should be able to decrypt task2_2_sym_key.enc with our private key and we should be able to decrypt task2_2.enc with the symmetric key you provide. Use 256-bit AES in CBC mode to encrypt the file.