CSCI 415/515: Fall 2023
Systems Programming
Extra Credit: cyphr.sh

Due: Tue, Dec, 19 11:59pm


In this project, you will implement cyphr.sh -- a shell script that wraps a few operations of the openssl utility. Specifically, cyphr.sh provides an easy interface for:

Name

cyphr.sh - encrypt and sign files

Synopsis

cyphr.sh [-h] [-g] [-e PASSWORD] [-s PRIVATE_KEY_FILE] [-e PASSWORD] [-v PUBLIC_KEY_FILE] INFILE OUTFILE

Options

-h

Print a usage statement to stdout and exit with status 0.

-g

Generate an RSA keypair. Here, INFILE is actually the path for storing the private key, and OUTFILE is the path for storing the public key.

-e PASSWORD

Encrypt INFILE using (a key derived from) PASSWORD. The ciphertext is written to the OUTFILE.

-d PASSWORD

Decrypt INFILE using (a key derived from) PASSWORD. The plaintext is written to the OUTFILE.

-s PRIVATE_KEY_FILE

Sign INFILE using PRIVATE_KEY_FILE. The OUTFILE is the same as INFILE, but with the signature prepended. If both -e and -s are given, first encrypt INFILE, then sign the ciphertext.

-s PUBLIC_KEY_FILE

Verify the signature on INFILE. If the signature is valid, skip over the signature and write the rest of INFILE to OUTFILE. If both -d and -v are given, first verify the file, then strip the signature and decrypt the rest of the file, writing the plaintext to OUTFILE.

OpenSSL Commands

The OpenSSL utility has many subcommands and options. To keep things simple (and facilitate grading), you must use the following OpenSSL commands:

RSA Key Generation

            openssl genpkey -algorithm RSA -out PRIVATE_KEY_FILE
            openssl pkey -in PRIVATE_KEY_FILE -pubout -out PUBLIC_KEY_FILE
            
The first command generates the private key file, and the second produces the public key file from the private one.
Encryption

            openssl enc -aes-256-cbc -pbkdf2 -pass pass:PASSWORD -in INPUT_FILE
            
Here, PASSWORD is the password and INPUT_FILE is the file to encrypt. By default, openssl writes the ciphertext to stdout; use the -out OUTPUT_FILE option to write the output to a file.
Decryption

            openssl enc -aes-256-cbc -d -pbkdf2 -pass pass:PASSWORD -in INPUT_FILE
            
Here, PASSWORD is the password and INPUT_FILE is the file to decrypt. By default, openssl writes the plaintext to stdout; use the -out OUTPUT_FILE option to write the output to a file.
Sign

            openssl dgst -sha256 -sign PRIVATE_KEY_FILE -out SIGNATURE_FILE INPUT_FILE
            
The above command signs INPUT_FILE using PRIVATE_KEY_FILE, and writes the signature to SIGNATURE_FILE.
Verify

            openssl dgst -sha256 -verify PUBLIC_KEY_FILE -signature SIGNATURE_FILE INPUT_FILE
            
The above command checks that SIGNATURE_FILE is a valid signature of INPUT_FILE that was produced using the private key that corresponds to PUBLIC_KEY_FILE.

Submitting

Submit your project as a zip file via gradescope. Your zip file should include a single file: cyphr.sh. Please refer to the instructions for submitting an assignment for details on how to login to gradescope and properly zip your project.

Rubric

Input Files: dog.txt

-h option


1.1 Print a usage statement (2 pts)


        ./cyphr.sh -h
        

Prints a usage statement to stdout. The statement must start with either Usage or usage; you decide the rest of the message. Conventionally, this option either prints the synopsis or a more verbose statement that also includes a description of the options.

1.2 Zero exit status (1 pts)


        ./cyphr.sh -h
        echo $?
        0
        

The exit status is zero.

-e option


2.1 Encrypt (6 pts)


        ./cyphr.sh -e abcd1234 dog.txt dog.enc
        

Encrypts dog.txt.

-d option


3.1 Decrypt (6 pts)


        ./cyphr.sh -d abcd1234 dog.enc dog.dec
        

Decrypts dog.enc. (We asssume dog.enc already exists.)

-g option


4.1 KeyGen (5 pts)


        ./cyphr.sh -g private.pem public.pem
        

Produces a public and private key file.

-s option


5.1 Sign (6 pts)


        ./cyphr.sh -s -private.pem dog.txt dog.sign
        

Signs dog.txt using the key in private.pem.

-v option


6.1 Valid signature (6 pts)


        ./cyphr.sh -v public.pem dog.sign dog.ver
        

Validates the signature on dog.sign and the original file contents to dog.ver. Assume that public.pem and dog.sign already exist.

6.2 Invalid signature (6 pts)


        ./cyphr.sh -v public-bad.pem dog.sign dog.ver
        

Fails to verify the document. (Assume that public-bad.pem and dog.sign already exist. cyphr.sh must (1) return a non-zero exit status, and (2) write at least one line to stderr. cyphr.sh must not create the file dog.ver.

Encrypt then Sign


7.1 Encrypt then sign (6 pts)


        ./cyphr.sh -e abcd1234 -s private.pem dog.txt dog.enc.sign
        

The command should produce dog.enc.sign by encrypting dog.txt and preprending a signature for the encrypted data. Assume that private.pem already exists.

Validate then Decrypt


8.1 Validate then decrypt (6 pts)


        ./cyphr.sh -d abcd1234 -v public.pem dog.enc.sign dog.ver.dec
        

Validates the signature on dog.enc.sign, and then decrypts the data, writing the original plaintext data to dog.ver.dec.