Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Data Encryption - no Integrity #4

Open
simonerni opened this issue Jan 3, 2020 · 3 comments
Open

Data Encryption - no Integrity #4

simonerni opened this issue Jan 3, 2020 · 3 comments

Comments

@simonerni
Copy link

The project uses an un-verified secret sharing scheme for the key, which can be sufficient given an appropriate thread model. But it should be detectable if the either the data or the key has been tampered with (of course, replacing them altogether is still possible, but the problem of authenticity is not tackled at all in this project, which again is ok for this project).

However, unauthenticated OFB encryption is used (essentially a stream cipher), which allows for arbitrary bitwise flips of the plaintext and is undetectable by this library.

Countermeasures:

  1. Verify that the contents of each threshold file are actually the same
  2. Use ChaCha20-Poly1305 as an AEAD scheme, instead of OFB.

It's no issue at the moment, as each key is only used once, but please use a random IV as well.

@jesseduffield
Copy link
Owner

Just to provide some context, I have switched to use Samir's Secret Sharing Scheme, meaning we only use one key (and we only use that key once). For that reason I believe an empty IV is sufficient. But I don't have a particularly strong background in encryption so please let me know if otherwise.

As for countermeasure 1, I think that should be easy enough. I can create a reader that reads from each horcrux in turn and validates that everything returns the same thing before writing that to the buffer. However when threshold == total we divide the encrypted content evenly between the horcruxes to save space. Do we still need to do something here to ensure integrity?

As for counter measure 2, could you give a little more context around the issue? My reading is that unauthenticated OFB encryption is bad because somebody could decrypt the content, then modify the plaintext, then re-encrypt it again, and you wouldn't know the plaintext had been modified. Is that correct? Also, looking up ChaCha20-Poly1305, I can't find examples of where I can use that in a streamed manner.

@simonerni
Copy link
Author

For the IV:
Yeah, an empty IV is ok for now, though my point is if you touch this library again in 4 years to extend it to encrypt multiple files, do you still know about this issue? Better to add it now.

Your reading is not entirely accurate, but I did not explain it in lots of details anyways. What you're essentially describing is an attacker that collects all horcruxes and replaces them with something else. This is not something that can defended against easily and would require some sort of signature of the entity creating the horcruxes, but I think we're leaving the scope of the library here and is an entirely different issue. This would be the property of authenticity.

However, I'm only focusing on integrity . My issue is that an attacker can modify the content of the file without knowing the key and it's not detectable (by the computer at least). It works by the attacker simply flipping some bits of the ciphertext.

If you look at how OFB works: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Output_Feedback_(OFB) then you can clearly see that the plaintext is simply XORed with some generated Bitstream (which is why OFB is kind of a stream cipher). For decryption, the same Bitstream is XORed with the ciphertext again.

An example, let's say you're encrypting the character 'A', in Bits this is:

01000001

now you XOR it with some random bits (10110011), yielding the cipher text:

11110010

Ok but now the attacker can flip any bit from this ciphertext and directly influence the bit at the plaintext that will be generated. If the attacker in addition knows what you're encrypting (maybe some well known prefix, your name, ....) then the attacker can easily influence the whole ciphertext by simply flipping the bits at the required places. The current scheme does nothing to prevent that.

For implementing the countermeasure:
Appending a MAC would also be possible, if authenticated encryption ciphers are not feasible to use. They usually operate in a block-mode, which is why there is probably no readily made stream implementation.

@jesseduffield
Copy link
Owner

Took me a while to get around to this but thanks for the detailed explanation @simonerni . Currently I'm spending most of my free time on https://github.com/jesseduffield/lazygit so I won't have time to implement this any time soon but I will happily review a PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants