From 8a1ec1d073dcd907fd98eb5af63e92b389e13052 Mon Sep 17 00:00:00 2001 From: Jan-Peter Klein Date: Wed, 2 Jul 2025 11:29:01 +0200 Subject: [PATCH] read file header instead of allBytes to determine Scheme --- .../common/recovery/MasterkeyService.java | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/cryptomator/common/recovery/MasterkeyService.java b/src/main/java/org/cryptomator/common/recovery/MasterkeyService.java index 5f89d3611..d150c7feb 100644 --- a/src/main/java/org/cryptomator/common/recovery/MasterkeyService.java +++ b/src/main/java/org/cryptomator/common/recovery/MasterkeyService.java @@ -13,15 +13,16 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardOpenOption; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Arrays; import java.util.List; import java.util.Optional; import java.util.UUID; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Stream; import static org.cryptomator.common.Constants.MASTERKEY_FILENAME; @@ -81,16 +82,28 @@ public final class MasterkeyService { } private static Optional determineScheme(Path c9rFile, byte[] masterkey) { - try { - ByteBuffer header = ByteBuffer.wrap(Files.readAllBytes(c9rFile)); - return Arrays.stream(CryptorProvider.Scheme.values()) - .filter(s -> isDecryptable(header, new Masterkey(masterkey), s)) - .findFirst(); - } catch (IOException e) { - LOG.info("Unable to detect Crypto scheme: Failed to decrypt .c9r file", e); - return Optional.empty(); - } + return Arrays.stream(CryptorProvider.Scheme.values()).filter(scheme -> { + try { + try (Masterkey mk = new Masterkey(masterkey); Cryptor cryptor = CryptorProvider.forScheme(scheme).provide(mk, SecureRandom.getInstanceStrong())) { + int headerSize = cryptor.fileHeaderCryptor().headerSize(); + + ByteBuffer headerBuf = ByteBuffer.allocate(headerSize); + + try (FileChannel channel = FileChannel.open(c9rFile, StandardOpenOption.READ)) { + channel.read(headerBuf, 0); + } + + headerBuf.flip(); + + return isDecryptable(headerBuf, mk, scheme); + } + } catch (IOException | CryptoException | NoSuchAlgorithmException e) { + LOG.info("Unable to detect Crypto scheme: Failed to decrypt .c9r file", e); + return false; + } + }).findFirst(); } + private static boolean isDecryptable(ByteBuffer header, Masterkey masterkey, CryptorProvider.Scheme scheme) { try (Cryptor cryptor = CryptorProvider.forScheme(scheme).provide(masterkey, SecureRandom.getInstanceStrong())) { cryptor.fileHeaderCryptor().decryptHeader(header.duplicate());