Question
encryptFile.java import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Scanner; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class encryptFile { // The crypt() function
encryptFile.java
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Scanner; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec;
public class encryptFile { // The crypt() function encrypts or decrypts a byte array input, using // an 16-byte initialization vector (init), 16-byte password (pass), // and an integer mode (either Cipher.ENCRYPT_MODE or Cipher.DECRYPT_MODE) public static byte[] crypt(byte[] input, byte[] init, byte[] pass, int mode) { // TODO - Fill this out. } // The cryptFile() function opens a file at a specified string path, // then passes in the init, pass, and mode values to the crypt() function // to either encrypt or decrypt the contents of the file. It then writes // the encrypted or decrypted data back to the file. Note that it should // overwrite the existing file - so don't try it on a file that's actually // worth anything! public static void cryptFile(String path, byte[] init, byte[] pass, int mode) { // TODO - Fill this out. } // The menu() function provides a user interface for the script. It should // prompt the user to enter a file path, 16-byte initialization vector, // 16-byte password, and a mode (encrypt or decrypt). If the password or // initialization vector are too short or too long, the function should // re-prompt the user to re-enter the value. public static void menu() { // TODO - Fill this out. }
// Just need to call the menu() function here public static void main(String[] args) { // Tests for crypt(); byte[] plain = "Hello World".getBytes(); byte[] pass = "aaaabbbbccccdddd".getBytes(); byte[] init = "gggggggggggggggg".getBytes(); byte[] cipher = crypt(plain, init, pass, Cipher.ENCRYPT_MODE); byte[] decrypted = crypt(cipher, init, pass, Cipher.DECRYPT_MODE); // This should print "Hello World" System.out.println(new String(decrypted)); // Uncomment below to test menu section once complete //menu(); }
}
than ideal - you generally want to use standardized implementations of cryptographic functions, as it's much less likely that they'll have internal defects or flaws that pose a security risk. For this lab, we'll use the javax.crypto libraries in Java. These libraries provide access to a number of cryptographically-related functions, including the ability to encrypt in AES and DES. A skeleton file has been provided called encryptFile.java. The crypt() function The first function we'll complete is the crypt() function. This function takes three byte arrays: an input, which is either a ciphertext or plaintext, a init, which is a 16 -byte initialization vector (for Chaining Block Mode), and a pass, which is a 16 -byte key. It also takes a mode, which is an integer. The Cipher module includes the modes declared as final static integers: Cipher.ENCRYPT_MODE Cipher.DECRYPT_MODE Inside the function, the first thing we need to do is pass the initialization vector and the password to the IvParameterSpec and SecretKeySpec objects respectively. These objects prepare the IV and password for use, and check that they are appropriate. They must each by 16 bytes in length, no longer and no shorter - this usually equals 16ASClI characters. The IV byte array can be passed directly into the constructor of a new IvParameterSpec object: new IvParameterSpec(init); However, when creating a SecretKeySpec object, you must also specify (in a String) the type of cipher that you are using. In our case, we'll use AES, and pass in our password byte array object: new SecretKeySpec(pass, "AES"); We can then create our Cipher object. Rather than use new like we do for most objects, we instead make a call to the Cipher.getInstance() function, passing in a String that defines several aspects of our cipher: - The cipher to be used (i.e. AES) - The mode of operation (i.e. CBC (chaining block cipher) or ECB (electronic code book) - The padding to be used (i.e. PKCS5 standard for padding) This will create a new Cipher object, which we can then use. Here's an example of what the getInstance() constructor should look like: Cipher.getInstance("AES/CBC/PKCSSPADDING"); Then, we need to call the init method on our new Cipher object. The init method takes three inputs: the integer mode, the SecretKeySpec object we created, and the IvParameterSpec that we created. Finally, we can perform our encryption/decryption. We'll take the input byte array and pass it to the dofinal() function of our initialized Cipher object. This will return a new byte array, which is our output. If we are performing encryption, the output will be our ciphertext; if we are performing decryption, the output will be our plaintext. You should then return this bytearray. Note that the above will require a try/except or a throws declaration around the Cipher-related lines. The cryptFile() function Now we have a function that can encrypt or decrypt byte arrays at will, so let's put it to use. The cryptFile() function takes a String path for a file, plus the bytearrays init and pass, and the integer mode. Inside of the function, we first need to check our file path and create a Path object. We can do this by just calling the Paths.get() function on our String path; this will return a new Path object. We can then get a bytearray of the file contents using the Files module, which has a function Files.readAllBytes(path). Pass in your Path object that you created. This will return a bytearray of the file contents. Pass the file contents as the input parameter to the crypt function, along with the init, pass, and mode parameters. This will return the bytearray output that is either a ciphertext or a plaintext (depending on if you are encrypting or decrypting). Finally, write the bytearray back to the original file using the Files.write() function. This takes the Path object and the bytearray as arguments: Files.write(file, output); This function will work with any type of file, including both plaintext and binary files. You will notice that binary files, like images, no longer work properly when encrypted. This is because the file header and related information is encrypted as well, and your computer will be unable to parse what the file is supposed to be. In order to make it readable again, you just need to decrypt the file using the same IV and password. You should verify this works by trying to encrypt a text file and an image. The menu() function Finally, let's put an interface on the script. This is fairly straightforward and just requires a couple Scanner calls to get user input, along with a couple loops to catch incorrect-length IV's and passwords. I'll leave this section up to you, but your code should: - Prompt the user to enter a filepath - Prompt for an initialization vector, and re-prompt if the user provides an IV that is not exactly 16 bytes in length (use a loop that checks the length() of the input bytearray). - Do the same as above, but for the password (make sure it's 16 bytes long) - Prompt the user for either "encrypt" or "decrypt", and then pass in the correct Cipher_MODE value (as shown earlier in this writeup). Here's an example of what the output should look like while in use: Enter File Path: src/tux.png Enter Initialization Vector (16 chars): aaabbbbccccdddd Enter Password ( 16 chars): hello Enter Password ( 16 chars): notlongenough Enter Password (16 chars): thisis16bytesyes Enter mode: encrypt or decrypt: encrypt Done The easiest way to do testing for this is to copy files directly into your Eclipse project folder, and then reference them with a path starting in src. This makes sure that you won't accidentally encrypt other files on your machine (possibly irreversibly). \& sre cosc232 > caesar.java > D demo.java > encryptFile.java > MyRandom.java > D sandbox.java > [D stream.java (D) test2.java tux.png Using DES The crypto library supports many different ciphers and encryption standards, including the DES and RSA encryption algorithms. Check out the documentation here: https://docs.oracle.com/iavase/7/docs/api/iavax/crypto/Cipher.html Create a new crypt() function (name of your choice) that implements an alternate cipher available in the Cipher object, and add a prompt to your menu() that allows the user to select between AES and the alternate cipher. When you are done, submit your finished Java file on the course Moodle PageStep by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started