Moving towards less configurability #10
Replies: 4 comments 5 replies
-
I believe reducing the amount of supported cryptographic primitives is a great idea. As do many other security folk, and cryptographers. Not only does it reduce the work for you, but you can choose secure cryptographic primitives with secure parameters (keeping users more secure). Having these parameters exposed to folk who are not educated about cryptography will increase the cognitive load, and possibly even cause anxiety (due to the unknown). As for faster folder encryption, could you extract each file from each folder within a directory (recursively), obtaining metadata, and encrypting it into one big file? When decrypted you could reconstruct the folder structure. Thus, there should be no meaningful difference between an encrypted file, or encrypted folder with Kryptor. You should consider using versioning for the Kryptor file formatting, a specification. So other developers may implement it, say for an Android app. |
Beta Was this translation helpful? Give feedback.
-
I checked out libsodium-core. Could you use this function for decryption and encryption of files? https://github.com/tabrath/libsodium-core/blob/master/src/Sodium.Core/SecretAeadXChaCha20Poly1305.cs |
Beta Was this translation helpful? Give feedback.
-
Hi @lynn-stephenson, thanks for the feedback/ideas as always :) It's definitely a sensible change. I was too inspired by VeraCrypt and KeePass/KeePassXC when I should have implemented something more like age. A lot of code can be cut now. That's an interesting idea that I haven't thought of, but I fear that it would be quite complex to implement, and I'm far from a good programmer. Combining the files into one file wouldn't be a problem, but retaining the folder structure and file names sounds like it would be difficult. It could also be slower since there would be a lot of folder structure information to read. I have no idea how fast it would be in practice, but I expect it wouldn't be any faster than encrypting files separately - the advantage being only having to create/open one output file. Versioning the file formatting/creating a specification sounds like a good idea. I'm not really sure how I'd go about that though, so I'd appreciate your advice. I'd like to keep the file format as simple as possible. Here's my current thinking for the planned speed improvements (some of this is repeat information from issues #6 & #8): Key Derivation
Folder Encryption
The simplicity of 1) is ideal, but it's arguably preferable to use different keys for different files. That's what Cryptomator and AxCrypt do, but they store the keys in files. Deriving subkeys would still be very fast compared to calling Argon2 for each file. The other problem is storing the salt for Argon2. If the salt is stored in a file inside the parent directory, then that's fine assuming the user doesn't want to individually decrypt a file in the directory. I suppose the alternative would be to store the salt in each file as well as in a dedicated file inside the parent directory, allowing for individual files to be decrypted. File Name Obfuscation
There are problems with both solutions. The Cryptomator way is faster as there's no file reading, but handling long file names would be tricky. Storing the file name in the file is messier and annoying to read in/remove correctly, but there's no length issue, the user can rename the file, and there's no need for separate keys for file name encryption. XChaCha20Poly1305The problem with using that function is that you need to load the entire file into memory to create one authentication tag, which doesn't work with very large files. However, I could increment the nonce and have lots of tags in the file - e.g. a tag for every 128 KiB buffer. This would require using a fixed size buffer. This is doable, but it would mean rekeying for folder encryption. I'm in two minds about the XChaCha20Poly1305 idea because it's worse from a security perspective compared to BLAKE2's much longer hash. Poly1305 is best for smaller messages rather than files. It's a shame BLAKE3 hasn't been implemented in libsodium yet because that would also bring a speed boost. Finally, out of curiosity, I had a look at the secretstream API. I found one .NET libsodium binding that contains the implementation, but the code is very untidy. The problem with implementing it myself is that I don't understand the secretstream state, which is a required parameter for the encryption/decryption functions. I find the naming in libsodium confusing as well. Edit: Improved XChaCha20Poly1305 comments. |
Beta Was this translation helpful? Give feedback.
-
I believe I've come up with a working solution for folder encryption and using XChaCha20Poly1305. Encryption
Decryption
Advantages
Limitations
Notes
Correction: The nonce for encrypting the DEK needs to be random to avoid rekeying when encrypting multiple files. It's easy to get confused writing DEK and KEK so many times. |
Beta Was this translation helpful? Give feedback.
-
I've been reading Real-World Cryptography by David Wong and have come to realise that allowing the user to configure things like the encryption algorithm and Argon2 parameters is a weakness rather than a strength of the application. That's why most encryption programs aren't configurable, with GPG being the exception, but GPG is a mess.
For instance, XSalsa20 is weaker than XChaCha20, so it shouldn't be an option. Therefore, I'm going to remove XSalsa20 in the next minor release. However, I've also decided to remove AES-CBC and just support XChaCha20. This means less code complexity - aka more readable, maintainable, and safer code. Furthermore, XChaCha20 is preferable for various reasons such as being faster.
Speaking of speed, it would be great to use libsodium's crypto_secretstream (XChaCha20Poly1305) as this would be faster than encrypting then calling BLAKE2, which results in the file being processed twice. However, secretstream isn't supported in the libsodium-core library, and the maintainer of the library has been very inactive for quite some time. So I'd either have to modify the library or write my own binding for libsodium.
I don't have time to write my own binding at the moment, although I would love to give that a go. On the other hand, I can look into modifying the libsodium-core library. This algorithm change wouldn't be implemented until v3.0.0 Beta at the earliest.
Finally, customisation of the Argon2 parameters is going to be a serious pain to sort out for the faster folder encryption I intend to implement in v3.0.0 Beta. For this reason and to prevent users from selecting weak parameters, I intend to make the Argon2 parameters non-adjustable. This will increase the key derivation time for individual files/multiple files when you don't select a folder, but this is a more secure approach. Folder encryption will probably be faster than selecting multiple separate files.
v2.3.0 Beta
As for what I'm during currently, I'm focusing on code improvements in the CLI version and will then move on to the GUI version (using the same code for the most part). After that, I just have to implement a few other changes and do lots of testing due to the code rewriting.
I was originally hoping to get v2.3.0 Beta out mid December, but that's not going to happen because of how many code changes I'm making and due to my academic workload. Expect the next release to be in January, all being well. I wish I could dedicate more time to this project to get things done faster, but sadly I can't. So please be patient as there are lots of improvements on the way.
Beta Was this translation helpful? Give feedback.
All reactions