Notes and Requirements for File Encryption and Authentication (FEA) Implementation

Alice would like to send a large file to Bob without disclosing the content of the file to anybody else. Alice also would like to make sure no other people can modify the message without being noticed. Unfortunately, Alice doesn’t share any secret key with Bob. The good news is that Alice and Bob know each other’s RSA public key. Assume Alice’s RSA private key is SKA, and her public key is PKA. Similarly, Bob’s RSA private key is SKB, and his public key is PKB.

We have developed a solution described in the class slides TO5.2_PublicKey_Crypto (31-33) . Your job is to develop a software tool that implements this solution for Alice and Bob.

  1. You are assumed to use Java. Before submitting your programs, test your code and make sure they can make and run. 
  2. Submit 2 files
  3. Your program should have three functionalities: (1) Generate a public/private key pair; (2) encrypt and sign a given file; and (3) verify and decrypt an encrypted and signed file.
  4. The first argument your program takes should be one of the following three commands: (1) genkey, (2) send, and (3) receive, corresponding to the three functionalities discussed above.
  5. When the command is "genkey", your program should generate a pair of 1024-bit RSA public/private keys, and then save the public key in a file named public_key and the private key in a file named private_key. In each of the key file, you should first save the modulus (128 bytes) and then the public or private key (128 bytes). The most significant byte should be stored first. You may consider using BigInteger.toArray () method to the bytes. For your reference, the command should be:

java FEA genkey

  1. When the command is "send", your program should take arguments as follows:

java FEA send [sender_private_key] [receiver_public_key] [plaintext file] [ciphertext file]

Your program should read the sender's private key stored in [sender_private_key] file, read the receiver's public key in [receiver_public_key] file, then encrypt and sign the [plaintext file] file, and finally save the result in a file named [ciphertext file]. You should use SHA-1 as the hash function before signing. You may specify this by providing a parameter "SHA1withRSA" to the Signature class, or hash it by yourself and then generate the signature. Note that the four file names are all provided by the user.

The output file should store E_{PKB}(Ks||IV) || E_{Ks}(F) || Sig_{SKA} (E_PKB(Ks||IV) || E_Ks(F)) in the exact order. The encryption of file F (i.e., E_{Ks}(F)) should be done with AES-128 in CBC mode with PKCS5Padding, where the encryption key is Ks and the initialization vector is IV. Logically, the output file consists of three components: The encrypted session key and IV E_{PKB}(Ks||IV), the encrypted file E_{Ks}(F), and the signature Sig_{SKA} (E_PKB(Ks||IV) || E_Ks(F)). When you store these components in file, each component should start with a 4 byte length fields indicating the number of bytes in this component (excluding the length field), with the remaining part stores the most significant byte first. As a result, the receiver can parse these components and read them into memory. For interoperability purposes, let us decide that the signature is generated over the concatenation of E_{PKB}(Ks||IV) and E_{Ks}(F) without the length field.

  1. When the command is "receive", your program should take argumentsas follows:

java FEA receive [receiver_private_key] [sender_public_key] [ciphertext file] [plaintext file]

Your program should read receiver's private key from the [receiver_private_key] file, read the sender's public key from [sender_public_key] file, then verify and decrypt the [ciphertext file] file, and finally save the recovered file in plaintext in a file named [plaintext file].

If the signature is valid, your program should display a message showing "Signature successfully verified..." and continue the operations described above. Before exiting, your program should print out the SHA-1 hash of the decrypted (i.e., original) file in Hexdecimal. Use all upper case letters for hexdecimal 'A' through 'F'. You may reuse your conversion function you wrote for HW#2.

However, if the signature is invalid, your program should display "Signature is invalid. The [ciphertext file] may have been modified or forged...", and then exit.

  1. When you save binary data (such as a public key and a ciphertext block) in a file, you are expected to store the most significant byte first. For example, the most significant byte of a public key should be the first byte in the public key file.
  2. You should test your program before submission. Check with TA's test vectors.
  3. Grading. If your program can run, you get 5 basic points. Your program will be tested again random files generated by the TA. You will get 5 points for each of the three commands.
  4. Submission: You need to submit your files online through Blackboard.

Test Vectors:

Download test vectors.

Please direct all questions about the text vectors to the TA.