Corrupted File Recovery

I’ve been using Cryptomator for four months now, and it’s been a wonderful experience. I have no corrupted files, I’m just curious about what the recovery process would be should I ever run into such an issue.

Let’s say I have a Cryptomator vault stored on external media. I mount the vault and add a file named Image.jpg. As a result of a single-event upset, a bit is flipped as (or after) the encrypted version of the file is being written to the disk. This means that on any subsequent decryption attempt of Image.jpg, the checksum match fails. By design, Cryptomator will show that the file exists, but will not read the mismatched file: there’s always the possibility that the file was tampered with maliciously. All other files which pass the checksum match can still be read as normal (a major security advantage of file-based encryption over monolithic vaults like VeraCrypt).

I have tested the behavior described above by intentionally modifying a single character of an encrypted file in Notepad++. My question is: how would I go about recovering Image.jpg? The vault health check in the Windows client reports no errors. The sanitizer hasn’t been updated in two years and doesn’t seem to work with the latest vault format (Exception in thread “main” java.lang.IllegalArgumentException: Unsupported vault version 999).

If the header was corrupted the file would understandably be unrecoverable, but this is statistically unlikely with a 5 MB JPG. A single bit flip in an unencrypted image of this size would probably not even be noticeable in most cases. For the record, I do keep backups. But still, is there any way to attempt a recovery of a file like this?

From my point of view only a solid backup strategy protects against data loss.
To answer your question: in your scenario I just would recover from one of my backups.

You could force the decryption and ignore the checksum mismatch. Due to the encryption scheme, only a single chunk is affected by the bit flip. Depending on the file format of the decrypted file, you can nearly recover everything.

Unfortunately, you cannot do this from the GUI currently.

Thank you for the thorough response! I was able to mount my test vault in the CLI. What CLI options should I use to ignore the checksum mismatch? I know this functionality has been previously requested.

This is the Linux command line output from attempting to decrypt image.jpg:

03:47:20.301 [Thread-343] ERROR o.c.frontend.fuse.ReadOnlyAdapter - read /image.jpg failed.
java.io.IOException: Unauthentic ciphertext in chunk 0
	at org.cryptomator.cryptofs.fh.ChunkCache.loadChunk(ChunkCache.java:41)
	at org.cryptomator.cryptofs.fh.ChunkCache.lambda$get$0(ChunkCache.java:56)
	at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4864)
	at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529)
	at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278)
	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155)
	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045)
	at com.google.common.cache.LocalCache.get(LocalCache.java:3962)
	at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4859)
	at org.cryptomator.cryptofs.fh.ChunkCache.get(ChunkCache.java:56)
	at org.cryptomator.cryptofs.ch.CleartextFileChannel.readLocked(CleartextFileChannel.java:108)
	at org.cryptomator.cryptofs.ch.AbstractFileChannel.read(AbstractFileChannel.java:155)
	at org.cryptomator.cryptofs.ch.AbstractFileChannel.read(AbstractFileChannel.java:139)
	at org.cryptomator.frontend.fuse.OpenFile.readNext(OpenFile.java:98)
	at org.cryptomator.frontend.fuse.OpenFile.read(OpenFile.java:55)
	at org.cryptomator.frontend.fuse.ReadOnlyFileHandler.read(ReadOnlyFileHandler.java:70)
	at org.cryptomator.frontend.fuse.ReadOnlyAdapter.read(ReadOnlyAdapter.java:230)
	at ru.serce.jnrfuse.AbstractFuseFS.lambda$init$3(AbstractFuseFS.java:138)
	at jnr.ffi.provider.jffi.NativeClosureProxy$$impl$$11.invoke(Unknown Source)
Caused by: org.cryptomator.cryptolib.api.AuthenticationFailedException: Authentication of chunk 0 failed.
	at org.cryptomator.cryptolib.v1.FileContentCryptorImpl.decryptChunk(FileContentCryptorImpl.java:98)
	at org.cryptomator.cryptolib.v1.FileContentCryptorImpl.decryptChunk(FileContentCryptorImpl.java:83)
	at org.cryptomator.cryptofs.fh.ChunkLoader.load(ChunkLoader.java:39)
	at org.cryptomator.cryptofs.fh.ChunkCache.loadChunk(ChunkCache.java:38)
	... 18 common frames omitted

You can’t do this over the CLI either. Right now one would need to implement/program this themself.