0
$\begingroup$

I need to encrypt file and directory names/paths but I need the encryption to be deterministic. I need to sync the local files with a cloud storage provider so I can't use probabilistic encryption.

Know that you should not use a static IV when encrypting text, would this be an acceptable work around:

  • Run passphrase through scrypt and store resulting output
  • Take the resulting output from scrypt and hash it (using MD5 for example)
  • Take the first 16 bytes of the hash and use it as the IV to encrypt the directory and file name

There is one thing to note that is really important here: The salt used for scrypt is hard coded most of the time. This is a local application that doesn't require a login and the users must be able decrypt the files on multiple computers so I'm unable to store the salts in a database like usual. The users can specify their own salt, but usually it will be hard coded for the application.

The only other thing I can think of:

  • Use probabilistic encryption
  • Read the directory/file structure from the cloud service provider and local directory
  • Map all the encrypted cloud provider names with their decrypted values
  • Map all the encrypted local names with their decrypted values
  • Sync based on the mappings found above

The only issue with that is that it is time consuming and really difficult to implement when using different cloud service providers.

$\endgroup$
8
  • $\begingroup$ This might be helpful to you Is it dangerous to encrypt lots of small files with the same key?. Why can't you use probabilistic encryption? $\endgroup$ – kelalaka Jan 10 at 1:14
  • $\begingroup$ @kelalaka The reason I can't use probabilistic encryption is because take this example of having two computers syncing between each other: Comp1: Creates file called 'test.txt' and it gets encrypted to 'iv:abc123' and syncs the file to gdrive. -> Comp2: Doesn't sync. Creates file called 'test.txt' and it gets encrypted to 'iv:bcd234' since the iv is different. -> Now Comp2 sync: since the two encrypted files had a different iv, their resulting names are different and so they can not sync together. $\endgroup$ – stackiee Jan 10 at 1:17
  • $\begingroup$ To be clear, I am using a unique IV when encrypting the file data. I am simply asking about encrypting the file name. $\endgroup$ – stackiee Jan 10 at 1:18
  • 2
    $\begingroup$ Derive the IV from filename + Directory? $\endgroup$ – kelalaka Jan 10 at 1:21
  • $\begingroup$ Would you recommend I concatenate them into a single string, hash he string using SHA256 and then just take half of the results (16 of the 32 bytes) and use that as my IV? Or is there a better way? @kelalaka $\endgroup$ – stackiee Jan 10 at 1:58
1
$\begingroup$

From my understanding of your question, what you want is to hide the name of the file, while enable syncing. You don't actually need encryption per se, since the real name of the file could be encrypted together with the entire file (probabilistically). As such, a potential solution is to just HMAC the file name and use that as the value for syncing. No IV or encryption is needed.

If you want to be able to invert this (if that's important), then you should use something like AES-SIV or AES-GCM-SIV (with fixed IV=0; in general, this isn't recommended but if these are really your constraints then this works). This will ensure that two files with parts of the name the same won't be discovered. You can of course do this also by deriving an IV and encrypting as you say, but that's more complicated and not standard. As such, it's not recommended.

My recommendation would be HMAC on the name for syncing, and regular probabilistic encryption on the name and full file.

$\endgroup$
4
  • $\begingroup$ This is a really interesting idea. The only downside I can see if that I have to now open the file to see the actual name. This means that when I sync locally, I need to open each file, get the first n bytes that hold the actual encrypted name, decrypt, and then display that to the user. This may be tough to do with a large folder structure. But other than that, this is a really great idea. If I use this method, can I reuse the key I get from scrypt, the one I use to encrypt the file content, as the secret key for the HMAC? $\endgroup$ – stackiee Jan 10 at 13:43
  • $\begingroup$ If you need two keys, then you should derive them. That is, if the key K is the one you have from scrypt, then do K1 = AES_K(0) and K2 = AES_K(1), and use K1 for the name and K2 for the file. $\endgroup$ – Yehuda Lindell Jan 10 at 14:14
  • $\begingroup$ I'm sorry, just to verify because I'm not quite sure I understand the 'AES_K(n)' notation. Currently my key length output for scrypt is 32. Would it suffice to change that to 64 and use half for the file encryption and half for HMAC? $\endgroup$ – stackiee Jan 10 at 14:28
  • $\begingroup$ I assume that you mean 32 bytes. Given that you are using a password, it would be enough to use 16 bytes as a key for each. So, no need to use AES to derive two keys. Indeed you can just take the first half and second half, but it's enough 16 bytes for each. $\endgroup$ – Yehuda Lindell Jan 10 at 15:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.