@@ -113,11 +113,6 @@ public static void encrypt(byte[] key, String inputPath, String outputPath) thro
113113 byte [] initVector = new byte [16 ];
114114 sr .nextBytes (initVector ); // 16 bytes IV
115115
116- // Display the Base64 encoded versions of Vector
117- System .out .print ("\n <---------------------------------------->\n " );
118- System .out .println ("IV is: " + Base64 .getEncoder ().encodeToString (initVector ));
119- System .out .print ("<---------------------------------------->\n \n " );
120-
121116 // Initialize Vector and Keys
122117 IvParameterSpec iv = new IvParameterSpec (initVector );
123118 SecretKeySpec skeySpec = new SecretKeySpec (key , ALGORITHM );
@@ -136,7 +131,15 @@ public static void encrypt(byte[] key, String inputPath, String outputPath) thro
136131 final Path plaintextFile = Paths .get (inputPath );
137132 final Path encryptedFile = Paths .get (outputPath );
138133
139- byte [] mac = computeMac (hmac , initVector , plaintextFile );
134+ // Compute Mac for authentication
135+ hmac .update (initVector );
136+ byte [] mac = computeMac (hmac , plaintextFile );
137+
138+ // Display the Base64 encoded versions of Vector and computed mac
139+ System .out .print ("\n <---------------------------------------->\n " );
140+ System .out .println ("IV is: " + Base64 .getEncoder ().encodeToString (initVector ));
141+ System .out .println ("Computed Mac: " + Base64 .getEncoder ().encodeToString (mac ));
142+ System .out .print ("<---------------------------------------->\n \n " );
140143
141144 // Write plaintext into ciphertext
142145 if (writeEncryptedFile (plaintextFile , encryptedFile , cipher , mac )) {
@@ -149,8 +152,8 @@ public static void encrypt(byte[] key, String inputPath, String outputPath) thro
149152 /**
150153 * Writes an encrypted version of the input file, into a new output file.
151154 * Uses a FileInputStream to read the plaintext file and wraps the OutputStream
152- * with a CipherOutStream to write an encrypted version of the plaintext file.
153- * Prior to writing the encrypted data, IV is saved as metadata in the encrypted
155+ * with a CipherOutStream to write an encrypted version. Prior to writing the
156+ * encrypted data, IV and the computed mac is saved as metadata in the encrypted
154157 * file with the use of a FileOutputStream. Returns True if the encryption writing
155158 * was successfull, False otherwise.
156159 *
@@ -165,9 +168,7 @@ private static boolean writeEncryptedFile(Path inputPath, Path outputPath, Ciphe
165168
166169 try (FileOutputStream fout = new FileOutputStream (outputPath .toFile ());) {
167170 // Write Metadata
168- fout .write (cipher .getIV ().length );
169171 fout .write (cipher .getIV ());
170- fout .write (mac .length );
171172 fout .write (mac );
172173
173174 try (CipherOutputStream cipherOut = new CipherOutputStream (fout , cipher );) {
@@ -185,8 +186,17 @@ private static boolean writeEncryptedFile(Path inputPath, Path outputPath, Ciphe
185186 return true ;
186187 }
187188
188- private static byte [] computeMac (Mac hmac , byte [] initVector , Path filePath ) {
189- hmac .update (initVector );
189+ /**
190+ * Computes a Message authencitaion code for a given inputfile
191+ * Takes in an initialised hmac which gets updated with the file's
192+ * contents line by line. Once completed the doFinal method will
193+ * return a byte array with the computed Mac.
194+ *
195+ * @param hmac Mac The initialised Mac object
196+ * @param filePath Path The file path
197+ * @return byte[] The file's computed Mac
198+ */
199+ private static byte [] computeMac (Mac hmac , Path filePath ) {
190200 try (InputStream fin = Files .newInputStream (filePath );) {
191201 final byte [] bytes = new byte [1024 ];
192202 for (int length = fin .read (bytes ); length != -1 ; length = fin .read (bytes )){
@@ -228,7 +238,7 @@ private static void generateKey() {
228238 * @throws IOException
229239 */
230240 public static void decrypt (byte [] key , String inputPath , String outputPath ) throws IOException ,
231- NoSuchAlgorithmException , NoSuchPaddingException {
241+ NoSuchAlgorithmException , NoSuchPaddingException , InvalidKeyException , InvalidAlgorithmParameterException {
232242
233243 File outputFile = new File (outputPath );
234244 // Create a new Output file if it doesn't exist
@@ -258,20 +268,22 @@ public static void decrypt(byte[] key, String inputPath, String outputPath) thro
258268 * @return boolean True if Decryption is successful False otherwise
259269 * @throws NoSuchPaddingException
260270 * @throws NoSuchAlgorithmException
271+ * @throws InvalidKeyException
261272 * @throws InvalidAlgorithmParameterException
262273 */
263274 private static boolean writeDecryptedFile (Path inputPath , Path outputPath , byte [] key ) throws NoSuchAlgorithmException ,
264- NoSuchPaddingException {
275+ NoSuchPaddingException , InvalidKeyException , InvalidAlgorithmParameterException {
265276 try (InputStream encryptedData = Files .newInputStream (inputPath );){
266277
267278 // Read metadata from the input file
268- byte [] initVector = new byte [encryptedData .read ()];
279+ byte [] initVector = new byte [16 ];
280+ byte [] givenMac = new byte [32 ];
281+
269282 encryptedData .read (initVector );
270- byte [] givenMac = new byte [encryptedData .read ()];
271283 encryptedData .read (givenMac );
272284
273285 // Create key specifications
274- IvParameterSpec iv = new IvParameterSpec (( initVector ) );
286+ IvParameterSpec iv = new IvParameterSpec (initVector );
275287 SecretKeySpec skeySpec = new SecretKeySpec (key , ALGORITHM );
276288 SecretKeySpec macKey = new SecretKeySpec (key , HASH_AlGORITHM );
277289
@@ -292,25 +304,19 @@ private static boolean writeDecryptedFile(Path inputPath, Path outputPath, byte[
292304 }
293305
294306 // Check authentication and file integerity
295- byte [] computedMac = computeMac (hmac , initVector , outputPath );
307+ hmac .update (initVector );
308+ byte [] computedMac = computeMac (hmac , outputPath );
296309 if (!Arrays .equals (givenMac , computedMac )) {
297310 throw new SecurityException ("Authentication failed, file may have been tampered with" );
298- } else {
299- LOG .info ("Authentication passed, file integrity maintained" );
300- }
311+ }
312+
313+ LOG .info ("Authentication passed, file integrity maintained" );
314+
301315
302316 } catch (IOException ex ) {
303317 Logger .getLogger (FileEncryptor .class .getName ()).log (Level .SEVERE , "IOException caught" );
304318 return false ;
305- } catch (InvalidKeyException e ) {
306- Logger .getLogger (FileEncryptor .class .getName ()).log (Level .SEVERE , "InvalidKeyException caught,"
307- + " please specify the correct Key" );
308- return false ;
309- } catch (InvalidAlgorithmParameterException e ) {
310- Logger .getLogger (FileEncryptor .class .getName ()).log (Level .SEVERE , "InvalidAlgorithmParameterException caught,"
311- + " file may have been modified, or invalid key was specified." );
312- return false ;
313- }
319+ }
314320 return true ;
315321 }
316322}
0 commit comments