An indistinguishable file format means more complicated parsing, and you don't want to leak the number of recipients. As such, I decided to use a fixed header format like before. This is simple but less efficient, adds constant storage overhead regardless of how many recipients you have, and limits the number of recipients to 20. However, this was the original limit with age and should rarely be a problem.
Whilst encrypted files are intended to be indistinguishable from random data, if an attacker knows that the same file has been encrypted many times, they may be able to determine the unpadded file length.
The headers are also fixed in size, so there's a range of small file sizes that Kryptor doesn't produce. Thus, files of the minimum length could be seen as an indicator that Kryptor was used. However, dummy random files could be stored to address this type of problem.
Why a pre-shared key instead of post-quantum algorithms?
- 2.Few protocols use post-quantum secure asymmetric algorithms, mostly experimental stuff. It won't become the norm for a long time.
- 3.Few cryptographic libraries support such algorithms, so you'd need extra dependencies and probably a custom .NET wrapper around a C library.
- 4.A hybrid solution would significantly complicate key pair generation and public key sharing. In contrast, pre-shared keys add minimal complexity; the main issue is sending them securely if encrypting a file to someone.
ChaCha20-Poly1305 is not as fast as algorithms like AEGIS and Rocca-S with hardware support. However, it's still fast, doesn't require hardware support, is widely used, and the cryptography is unlikely to be a performance bottleneck compared to disk IO. With that said, ChaCha20-Poly1305 will likely be replaced in the future.
If an attacker has physical or remote access to your machine, they could retrieve sensitive data (e.g. encryption keys) whilst Kryptor is running. This is quite literally impossible to prevent.
However, Kryptor does attempt to zero out sensitive data as soon as possible from memory. With pinning, this should be guaranteed, but sometimes pinning can't be used. For example, non-interactive string inputs (e.g. pre-shared keys) can't be erased from memory and will unfortunately get leaked into the process table/shell history.