diff --git a/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java b/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java index d63f63309..e9fecddc3 100644 --- a/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java +++ b/main/crypto-aes/src/main/java/org/cryptomator/crypto/aes256/Aes256Cryptor.java @@ -300,13 +300,13 @@ public class Aes256Cryptor extends AbstractCryptor implements AesCryptographicCo * {@link FileNamingConventions#LONG_NAME_FILE_EXT}. */ private String encryptPathComponent(final String cleartext, final SecretKey key, CryptorIOSupport ioSupport) throws IllegalBlockSizeException, BadPaddingException, IOException { - final byte[] ivRandomPart = randomData(FILE_NAME_IV_LENGTH); + final long cleartextHash = crc32Sum(cleartext.getBytes()); final ByteBuffer iv = ByteBuffer.allocate(AES_BLOCK_LENGTH); - iv.put(ivRandomPart); + iv.putLong(cleartextHash); final Cipher cipher = this.cipher(FILE_NAME_CIPHER, key, iv.array(), Cipher.ENCRYPT_MODE); final byte[] cleartextBytes = cleartext.getBytes(Charsets.UTF_8); final byte[] encryptedBytes = cipher.doFinal(cleartextBytes); - final String ivAndCiphertext = ENCRYPTED_FILENAME_CODEC.encodeAsString(ivRandomPart) + IV_PREFIX_SEPARATOR + ENCRYPTED_FILENAME_CODEC.encodeAsString(encryptedBytes); + final String ivAndCiphertext = Long.toHexString(cleartextHash) + IV_PREFIX_SEPARATOR + ENCRYPTED_FILENAME_CODEC.encodeAsString(encryptedBytes); if (ivAndCiphertext.length() + BASIC_FILE_EXT.length() > ENCRYPTED_FILENAME_LENGTH_LIMIT) { final String crc32 = Long.toHexString(crc32Sum(ivAndCiphertext.getBytes())); @@ -354,11 +354,10 @@ public class Aes256Cryptor extends AbstractCryptor implements AesCryptographicCo throw new IllegalArgumentException("Unsupported path component: " + encrypted); } - final String ivRandomPartStr = StringUtils.substringBefore(ivAndCiphertext, IV_PREFIX_SEPARATOR); + final String cleartextHash = StringUtils.substringBefore(ivAndCiphertext, IV_PREFIX_SEPARATOR); final String ciphertext = StringUtils.substringAfter(ivAndCiphertext, IV_PREFIX_SEPARATOR); - final byte[] ivRandomPart = ENCRYPTED_FILENAME_CODEC.decode(ivRandomPartStr); final ByteBuffer iv = ByteBuffer.allocate(AES_BLOCK_LENGTH); - iv.put(ivRandomPart); + iv.putLong(Long.parseLong(cleartextHash, 16)); final Cipher cipher = this.cipher(FILE_NAME_CIPHER, key, iv.array(), Cipher.DECRYPT_MODE); final byte[] encryptedBytes = ENCRYPTED_FILENAME_CODEC.decode(ciphertext); diff --git a/main/crypto-aes/src/test/java/org/cryptomator/crypto/aes256/Aes256CryptorTest.java b/main/crypto-aes/src/test/java/org/cryptomator/crypto/aes256/Aes256CryptorTest.java index e670cb64b..0c71c6382 100644 --- a/main/crypto-aes/src/test/java/org/cryptomator/crypto/aes256/Aes256CryptorTest.java +++ b/main/crypto-aes/src/test/java/org/cryptomator/crypto/aes256/Aes256CryptorTest.java @@ -134,15 +134,19 @@ public class Aes256CryptorTest { // short path components final String originalPath1 = "foo/bar/baz"; - final String encryptedPath1 = cryptor.encryptPath(originalPath1, '/', '/', ioSupportMock); - final String decryptedPath1 = cryptor.decryptPath(encryptedPath1, '/', '/', ioSupportMock); + final String encryptedPath1a = cryptor.encryptPath(originalPath1, '/', '/', ioSupportMock); + final String encryptedPath1b = cryptor.encryptPath(originalPath1, '/', '/', ioSupportMock); + Assert.assertEquals(encryptedPath1a, encryptedPath1b); + final String decryptedPath1 = cryptor.decryptPath(encryptedPath1a, '/', '/', ioSupportMock); Assert.assertEquals(originalPath1, decryptedPath1); // long path components final String str50chars = "aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeee"; final String originalPath2 = "foo/" + str50chars + str50chars + str50chars + str50chars + str50chars + "/baz"; - final String encryptedPath2 = cryptor.encryptPath(originalPath2, '/', '/', ioSupportMock); - final String decryptedPath2 = cryptor.decryptPath(encryptedPath2, '/', '/', ioSupportMock); + final String encryptedPath2a = cryptor.encryptPath(originalPath2, '/', '/', ioSupportMock); + final String encryptedPath2b = cryptor.encryptPath(originalPath2, '/', '/', ioSupportMock); + Assert.assertEquals(encryptedPath2a, encryptedPath2b); + final String decryptedPath2 = cryptor.decryptPath(encryptedPath2a, '/', '/', ioSupportMock); Assert.assertEquals(originalPath2, decryptedPath2); }