mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-05-14 08:41:28 +00:00
non-interchangable chunks by adding additional data to MACs
This commit is contained in:
@@ -423,6 +423,7 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration {
|
||||
final InputStream in = new SeekableByteChannelInputStream(encryptedFile);
|
||||
byte[] buffer = new byte[CONTENT_MAC_BLOCK + 32];
|
||||
int n = 0;
|
||||
long blockNum = 0;
|
||||
while ((n = IOUtils.read(in, buffer)) > 0) {
|
||||
if (n < 32) {
|
||||
throw new DecryptFailedException("Invalid file content, missing MAC.");
|
||||
@@ -430,6 +431,8 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration {
|
||||
|
||||
// check MAC of current block:
|
||||
if (authenticate) {
|
||||
contentMac.update(iv);
|
||||
contentMac.update(longToByteArray(blockNum));
|
||||
contentMac.update(buffer, 0, n - 32);
|
||||
final byte[] calculatedMac = contentMac.doFinal();
|
||||
final byte[] storedMac = new byte[32];
|
||||
@@ -444,6 +447,7 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration {
|
||||
final int plaintextLengthWithoutPadding = (int) Math.min(plaintext.length, fileSize - bytesDecrypted); // plaintext.length is known to be a 32 bit int
|
||||
plaintextFile.write(plaintext, 0, plaintextLengthWithoutPadding);
|
||||
bytesDecrypted += plaintextLengthWithoutPadding;
|
||||
blockNum++;
|
||||
}
|
||||
destroyQuietly(fileKey);
|
||||
|
||||
@@ -521,6 +525,7 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration {
|
||||
final InputStream in = new SeekableByteChannelInputStream(encryptedFile);
|
||||
byte[] buffer = new byte[CONTENT_MAC_BLOCK + 32];
|
||||
int n = 0;
|
||||
long blockNum = startBlock;
|
||||
while ((n = IOUtils.read(in, buffer)) > 0 && bytesWritten < length) {
|
||||
if (n < 32) {
|
||||
throw new DecryptFailedException("Invalid file content, missing MAC.");
|
||||
@@ -528,6 +533,8 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration {
|
||||
|
||||
// check MAC of current block:
|
||||
if (authenticate) {
|
||||
contentMac.update(iv);
|
||||
contentMac.update(longToByteArray(blockNum));
|
||||
contentMac.update(buffer, 0, n - 32);
|
||||
final byte[] calculatedMac = contentMac.doFinal();
|
||||
final byte[] storedMac = new byte[32];
|
||||
@@ -546,6 +553,7 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration {
|
||||
|
||||
plaintextFile.write(plaintext, offset, currentBatch);
|
||||
bytesWritten += currentBatch;
|
||||
blockNum++;
|
||||
}
|
||||
return bytesWritten;
|
||||
} finally {
|
||||
@@ -593,12 +601,16 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration {
|
||||
// writing ciphered output and MACs interleaved:
|
||||
final byte[] buffer = new byte[CONTENT_MAC_BLOCK];
|
||||
int n = 0;
|
||||
long blockNum = 0;
|
||||
while ((n = IOUtils.read(in, buffer)) > 0) {
|
||||
final byte[] ciphertext = cipher.update(buffer, 0, n);
|
||||
out.write(ciphertext);
|
||||
contentMac.update(iv);
|
||||
contentMac.update(longToByteArray(blockNum));
|
||||
contentMac.update(ciphertext);
|
||||
final byte[] mac = contentMac.doFinal();
|
||||
out.write(mac);
|
||||
blockNum++;
|
||||
}
|
||||
destroyQuietly(fileKey);
|
||||
|
||||
@@ -623,4 +635,8 @@ public class Aes256Cryptor implements Cryptor, AesCryptographicConfiguration {
|
||||
return plaintextSize;
|
||||
}
|
||||
|
||||
private byte[] longToByteArray(long lng) {
|
||||
return ByteBuffer.allocate(Long.SIZE).putLong(lng).array();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user