Skip to content

Commit ee6b614

Browse files
committed
feat: compute mac method accepts metadata as arguments
1 parent 6033da7 commit ee6b614

File tree

1 file changed

+20
-23
lines changed

1 file changed

+20
-23
lines changed

src/FileEncryptor.java

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@
2626
import javax.crypto.spec.PBEKeySpec;
2727
import javax.crypto.spec.SecretKeySpec;
2828

29-
30-
31-
3229
/**
3330
*
3431
* @author Erik Costlow
@@ -82,10 +79,10 @@ public static void main(String[] args) throws Exception {
8279

8380
/**
8481
* Encrypts a plain text input file by outputing an encrypted version. It does this
85-
* generating a 128 bit secret key and initialisation vector which are used as the
86-
* specifications during the file encryption process. A message aithentication code
87-
* is also computed with the intialisaton vector and plaintext values, hence these
88-
* values can be checked for tampering during decryption.
82+
* generating a secret key from a passowrd and an initialisation vector which are
83+
* used as the specifications during the file encryption process. A message
84+
* authentication code is also computed and initialised with the vector and plaintext
85+
* values, hence they can be checked for tampering during decryption.
8986
*
9087
* @param password char[] The password specified by the user
9188
* @param inputPath String specifying the Input path of the plaintext file
@@ -113,7 +110,6 @@ public static void encrypt(char[] password, String inputPath, String outputPath)
113110
Arrays.fill(password, '\0'); password = null;
114111

115112
SecretKeySpec macKeySpec = new SecretKeySpec(macKey, HASH_AlGORITHM);
116-
117113
Mac hmac = Mac.getInstance(HASH_AlGORITHM);
118114
hmac.init(macKeySpec);
119115

@@ -125,8 +121,7 @@ public static void encrypt(char[] password, String inputPath, String outputPath)
125121
final Path encryptedFile = Paths.get(outputPath);
126122

127123
// Compute Mac for authentication
128-
hmac.update(initVector); hmac.update(salt); hmac.update(macSalt);
129-
final byte[] mac = computeMac(hmac, plaintextFile);
124+
final byte[] mac = computeMac(hmac, plaintextFile, initVector, salt, macSalt);
130125

131126
// Display the Base64 encoded versions of Key, Vector and computed mac
132127
displayInformation(getPair("Secret Key", key), getPair("Init Vector", initVector), getPair("Salt", salt),
@@ -163,10 +158,7 @@ private static boolean writeEncryptedFile(Path inputPath, Path outputPath, Ciphe
163158

164159
try (FileOutputStream fout = new FileOutputStream(outputPath.toFile());) {
165160
// Write Metadata
166-
fout.write(cipher.getIV());
167-
fout.write(salt);
168-
fout.write(macSalt);
169-
fout.write(mac);
161+
fout.write(cipher.getIV()); fout.write(salt); fout.write(macSalt); fout.write(mac);
170162

171163
try (CipherOutputStream cipherOut = new CipherOutputStream(fout, cipher);) {
172164
final byte[] bytes = new byte[1024];
@@ -186,7 +178,8 @@ private static boolean writeEncryptedFile(Path inputPath, Path outputPath, Ciphe
186178
/**
187179
* Decrypts a given cipertext file into its original plaintext form.
188180
* A successful decryption occurs when provided with the right password
189-
* to create the Cipher specifications required for decryption.
181+
* to create the Cipher specifications required for decryption. The
182+
* decryption will also fail if any tampering were to be observed.
190183
* Will overwrite the resultant output file if it already exists.
191184
*
192185
* @param password char[] The password specified by the user
@@ -222,7 +215,7 @@ public static void decrypt(char[] password, String inputPath, String outputPath)
222215
* The encrypted files gets decrypted and written out to the output file.
223216
* For a successful decryption the Cipher needs to be initialized in DECRYPT mode
224217
* with the correct key and vector specifications. The IV, salts and mac is read
225-
* from the encrypted file as it was saved unencrypted during the encryption process.
218+
* from the encrypted file as it was saved as metadata during the encryption process.
226219
* Decryption will also fail if the computed authentication code doesn't match with
227220
* the given authentication code.
228221
*
@@ -270,9 +263,7 @@ private static boolean writeDecryptedFile(Path inputPath, Path outputPath, char[
270263
// Check authentication and file integerity
271264
Mac hmac = Mac.getInstance(HASH_AlGORITHM);
272265
hmac.init(macKeySpec);
273-
274-
hmac.update(initVector); hmac.update(salt); hmac.update(macSalt);
275-
final byte[] computedMac = computeMac(hmac, outputPath);
266+
final byte[] computedMac = computeMac(hmac, outputPath, initVector, salt, macSalt);
276267

277268
if (!Arrays.equals(givenMac, computedMac)) {
278269
throw new SecurityException("Authentication failed, file may have been tampered with");
@@ -349,15 +340,21 @@ private static Cipher createCipher(byte[] key, byte[] initVector, int mode) thro
349340

350341
/**
351342
* Computes a Message authencitaion code for a given inputfile
352-
* Takes in an initialised hmac which gets updated with the file's
353-
* contents line by line. Once completed the doFinal method will
354-
* return a byte array with the computed Mac.
343+
* and any metadata that will be added to the file. Takes in an
344+
* initialised hmac which gets updated with the file's contents
345+
* line by line. Once completed the doFinal method will return a
346+
* byte array with the computed Mac.
355347
*
356348
* @param hmac Mac The initialised Mac object
357349
* @param filePath Path The file path
350+
* @param metadata byte[] Metadata that will be added to the input file
358351
* @return byte[] The file's computed Mac
359352
*/
360-
private static byte[] computeMac(Mac hmac, Path filePath) {
353+
private static byte[] computeMac(Mac hmac, Path filePath, byte[]... metadata) {
354+
// feed metadata into mac
355+
for (byte[] data : metadata) { hmac.update(data); }
356+
357+
// feed input file into mac
361358
try (InputStream fin = Files.newInputStream(filePath);) {
362359
final byte[] bytes = new byte[1024];
363360
for(int length = fin.read(bytes); length != -1; length = fin.read(bytes)){

0 commit comments

Comments
 (0)