Releases: samuel-lucas6/Kryptor
v4.1.0
Added
- Support for changing a private key passphrase via
-m|--modify
. - Support for a comment after a public/private key string in
.public
/.private
files, either manually by opening such files in a text editor or by specifying-c|--comment
during key pair generation. Note that these comments are not authenticated in any way.
Changed
- The
-a|--about
option has been replaced with--version
to align with other tools. - There's no longer a new line before output to the terminal.
Bad signature
now has an exit code of-1
.- Errors should be written to stderr.
- Updated dependencies/.NET.
Removed
- The
-u|--update
option to align with other tools. Just use a package manager.
v4.0.1
Removed
- Support for v1 private and public keys. Please see the v4.0.0 release for more information.
- The dependencies for v1 key pairs.
Changed
- 'Password' has been renamed to 'passphrase'. The option is now
-p|--passphrase
. - Random passphrases are now lowercase to allow easy typing.
- The public/private key file length checks have been moved.
- Various error messages have been shortened/rephrased.
- Updated dependencies and the .NET SDK/runtime.
Fixed
InsufficientMemoryException
if you don't have enough memory to use Argon2.
v4.0.0
Warning
This release contains many breaking changes. If you're updating from a previous version of Kryptor, please decrypt all of your files using your current version.
After many hours and much indecision, the next major version of Kryptor is here. It's not perfect; there are still a few things I'm not entirely happy about. However, it's definitely an improvement on v3. I just hope I haven't missed anything, and please bear with me whilst I update the website.
Deprecated
- Support for the previous private key format will be removed in a future release. The format is automatically updated when you use your private key for the first time.
- Similarly, support for the previous public key format will be removed in a future release. Again, the format is automatically updated when your private key is. Alternatively, you can use
-r|--recover
.
Note
You should republish/share your new public key string/file in place of the old one and back up your new private key file. However, your key pair doesn't actually change. The private key gets re-encrypted, and the public key has a different header, so the string looks different.
Added
- The new encryption format is intended to be indistinguishable from random to limit metadata. This means no identifiable headers and randomised padding. Few tools do this (e.g. age doesn't care about metadata). A huge thanks to Monocypher for Elligator 2 and Covert Encryption for inspiration and their randomised padding scheme.
- Directories are now converted into ZIP files (with no compression for speed) before being encrypted. This means an encrypted directory is indistinguishable from an encrypted file.
- You can now specify up to 20 public key recipients for a single file. It used to be limited to 1 recipient.
- Support for pre-shared keys has been added to provide optional post-quantum security when encrypting a file to someone's public key.
- Pre-shared keys can also be used for file encryption alone like keyfiles. This is a faster alternative to password-based encryption.
- Some of the encrypted metadata header is currently empty, which will eventually be used for storing the file timestamps and cross-platform attributes. The timestamps of the encrypted file can then be altered to further limit metadata. This all needs more thought and some study of digital forensics though.
- You can now sign each file in a directory. This is handy for signing software releases quickly.
- Multiple signatures can now be verified at once.
- Multiple custom signature paths can be specified at once for signing.
- Key pairs can be generated non-interactively.
- macOS ARM64 and Linux ARM64 are now officially supported and can be updated using
-u|--update
. - A
-1
exit code is returned when an error occurs.
Changed
- Switched from XChaCha20-BLAKE2b to ChaCha20-Poly1305 for encryption. It's faster and standardised. The padding fix is applied when encrypting the metadata header to add key commitment.
- Now using a little-endian counter nonce and the STREAM construction. A random nonce is unnecessary in this use case, especially since it was being incremented for each chunk before anyway. Then the STREAM construction has become unofficially standardised and is more flexible.
- The Argon2 parameters have been reduced as they were excessive and much slower than I thought on other machines. This speeds up password-based key derivation whilst retaining a good security margin.
- Passwords are no longer prehashed. This was done previously for consistency with how peppering was done.
- The pepper is now used as input keying material for key derivation after password hashing instead of being used as a key prior to password hashing. This was done to save an extra call to BLAKE2b.
- Using a keyfile alone no longer uses Argon2 as random keyfiles are high in entropy.
- Keyfile hashing has been made compatible with the pre-shared key format, and random keyfiles are now 32 bytes in size instead of 64 bytes.
- The previous authentication tag is no longer used as associated data. This was unnecessary and came with a performance cost.
- Both public keys are included in the key derivation for shared secrets.
- The long-term and ephemeral shared secrets are concatenated the other way around to comply with the Noise Protocol Framework.
- The ephemeral public key is used as info in the wrap key derivation instead of being used as associated data. With passwords/pre-shared keys, this is actually an additional 256-bit random salt since no public key is used.
- The encrypted metadata header has been rearranged. The file length is now stored instead of the amount of padding. The file name is also stored there and padded to 256 bytes.
- Private keys are now encrypted using ChaCha20-Poly1305 with the padding fix for key commitment and an all zero nonce since the key is unique.
- The public/private key headers have been changed to make the algorithm readable at the beginning of the string (
Cu//
for Curve25519 andEd//
for Ed25519). - Geralt, my libsodium binding, is now used instead of libsodium-core.
- Thanks to Geralt, spans are used instead of byte arrays when possible for improved performance and fewer allocations.
- Sensitive bytes are pinned when possible/sensible so they can be zeroed properly.
- FileStream performance should be improved as the buffer size is now adjusted based on the size of the file and output files are preallocated on disk.
- Random file name generation has been improved due to Geralt.
- File names are checked for invalid characters to prevent problems storing the file name/decrypting cross-platform.
- libsodium is used for Base64 encoding, which is done in constant time.
- Lots of wrapper classes have been removed due to Geralt.
- It's now clearer when you're being asked for a private key password compared to a regular password.
- 'Directory' is used instead of 'folder' in messages.
- Some error messages have been made more consistent.
- Blue is no longer used for any messages; orange (technically 'dark yellow') is used instead.
- The initial validation has been improved.
- Code has been spaced out for readability, Geralt constants are used, and the if/loop braces style has been changed.
Fixed
- Early returns when an exception was thrown during decryption, potentially preventing some files from being processed.
- An empty file name in error messages when the path ends in a directory/volume separator character.
- An unhandled directory
UnauthorizedAccessException
during empty directory validation. - 'name (2)' getting restored to 'name (3)' instead of 'name (2) (2)' if 'name (2)' exists decrypting a file that had its name encrypted. I don't like this numbering, but it's the safest approach I can come up with.
- Removing double digit file name numbers (e.g. 'name (10)').
- The resources are now embedded when building as well as publishing.
- The publish profiles for ARM64.
- Probably some other stuff I've neglected to mention.
v3.1.1
This is a very quick, unpolished hotfix release due to the severity of issue #40 (explained below), which was reported via email yesterday. I have exams starting within the next few weeks, so no more releases are planned until afterwards in the summer, and there will probably be few code updates until then.
Fixed
- Files with a certain length would accidentally have the last 16,384 byte chunk removed during decryption due to a mathematical mistake that wasn't detected during any of my testing because of the file sizes of my test files. I'm extremely sorry for any trouble this causes. It's rather crushing as a maintainer when something like this happens, but I would like to again thank the person who reported this issue.
- Chocolatey installs hopefully won't have a
vcruntime140.dll
extraction error anymore. I'm also working on adding the package equivalent of this file as a dependency.
Changed
- Encrypted files are no longer deleted by default when decrypting. The
-o|--overwrite
option now needs to be specified to do this. - Illegal characters from file/directory names are now rejected with an error rather than being silently removed. As this was taken from a v4 commit, with v4 encrypting directories differently, this change won't work with subdirectories.
- 'Decrypting private key...' is displayed instead of 'Deriving encryption key from password...' for private key decryption to avoid confusion.
- The dependencies and
vcruntime140.dll
files have been updated.
Added
- A message saying to back up the private key file when generating a new key pair.
- A message saying to back up the keyfile when generating a random keyfile.
- Publish profiles for Linux ARM64 and macOS ARM64 to build from source more easily. Builds for these platforms may be included in releases for v4 onwards.
v3.1.0
Security
- Patched a potential directory traversal attack vulnerability when decrypting a file/folder someone sent you that contained a malicious file name. I say potential because I have not attempted to exploit the attack, and this type of vulnerability primarily affects web applications. However, it has also affected ZIP libraries and encryption libraries.
Added
- Non-interactive password support, meaning you can now do
-p:"[password]"
instead of entering the password interactively. To randomly generate a password, you can type a space:-p:" "
. However, entering a password interactively is still more secure as it hides your password and avoids using a string variable. - Exporting the recovered public key from
-r|--recover
to a.public
file if one does not exist in the same directory as the.private
key file. - Automatic
vcruntime140.dll
extraction on Windows to always ensure that the libsodium cryptographic library is portable. -u|--update
can now install updates for you. This checks the download signatures automatically, ensuring authenticity and integrity, and replaces thekryptor
executable in place.- Coloured error messages (red) and successful messages (green). Blue and orange are also used but rarely.
- A note in
-h|--help
about having to surround file names/paths with "speech marks".
Changed
- Switched to .NET 6.
- The
-f|--obfuscate
option has been renamed to-n|--names
. I will now be calling it file name encryption rather than file name obfuscation. - Path.GetRandomFileName() is no longer being used because the documentation was updated to remove the claim that it is cryptographically secure.
- It is now possible to sign
.signature
files. - The spacing in the output text has been changed to try and make things more readable.
- File names in the output text are now surrounded by "speech marks" to help distinguish them from other text.
- Lots of code improvements to reduce the line count.
- Various error messages have been improved.
Fixed
- The authenticated comment is no longer shown if it is empty when verifying a signature.
- Folders containing only empty subdirectories are now detected as containing no files, leading to an error.
- String.Replace() is no longer used for file paths since it may cause problems by removing multiple parts of a string.
- Illegal file name characters are now removed from the file name before it is stored during file name encryption because this could cause issues decrypting the file on another operating system. This may be switched to an error in the future.
- The total count should now be correct when decrypting a directory with an incorrect salt length.
v4.0.0 Roadmap
As a reminder, lots of improvements and breaking changes will be coming in v4, and you can follow my progress via the Roadmap and Projects tab. It will take a while to get this release out because of university and writing a custom libsodium binding.
v3.0.4
- Fixed a bug when encrypting/decrypting 0 byte files (please see #27).
- Fixed a bug related to renaming duplicated files (please see #28).
- Added a '
Deriving encryption key from the password...
' message to explain the key derivation delay. - Added '
Encrypting [file] => [file.kryptor]...
' and 'Decrypting [file.kryptor] => [file]...
' messages to indicate that Kryptor is doing something rather than frozen when encrypting/decrypting large files. - Added '
Commencing encryption of [directory] directory...
' and 'Commencing decryption of [directory] directory...
' messages to help separate the folder encryption output from the file encryption output. - Now displaying the name of randomly generated keyfiles.
- The
-s|--sign
and-v|--verify
validation has been improved. - Fixed an
UnauthorizedAccessException
when trying to randomly generate a keyfile to a path where a keyfile by that name already exists. - Various code improvements, although there's still lots to go through. More code improvements will be coming in the next release.
If you're interested in where Kryptor is heading, then please take a look at the new Roadmap. However, development will slow down a little over the coming months as I'm going back to university for my busiest year yet.
v3.0.3
The first stable release of Kryptor!
- Validation for file paths now happens before being asked to enter a password.
- Added empty directory validation.
- Added a validation check for a salt file when encrypting directories.
- Added a validation check for a salt file when decrypting directories using a private key.
- The total number of files count is no longer reduced when a file is invalid (e.g. already encrypted).
- Removed error logging. It is not needed, and the log file never got shared in bug reports.
- Added a private key encryption example to
-h|--help
to clarify that you do not need to specify your public key when encrypting files for yourself. - Simplified the examples in
-h|--help
. - Reworded several error messages.
v3.0.2-beta
- Fixed the UnauthorizedAccessException when overwriting read-only files.
- Fixed the UnauthorizedAccessException when storing the file name if the file was read-only.
- Now restoring the
-o|--overwrite
setting if an exception occurs during directory encryption. - Now displaying the name of the copied/backup directory when encrypting a directory without the
-o|--overwrite
option. - Now renaming the copied/backup directory to the original directory name if possible (if
-f|--obfuscate
is specified and-o|--overwrite
is not). The directory can't be renamed otherwise because two directories cannot have the same path.
v3.0.1-beta
- Now including the
vcruntime140.dll
file in the Windows release so the application is portable without the Visual C++ runtime installed. I forgot to include this in the v3.0.0 Beta release. 🤦♂️ - Minor changes to
-a|--about
.
v3.0.0-beta
After just over 2 months of work, v3 is finally done🎉 I recommend reading the new documentation to get up to speed.
- Chunked AEAD for encryption.
- New KEK/DEK design.
- File signing.
- Fixed Argon2 parameters.
- Faster directory encryption.
- Authenticated hybrid file encryption.
- Masked password entry with support for random passphrase generation.
- Separate encryption and signing asymmetric keys.
- Private key encryption.
- Export asymmetric key pairs.
- Code improvements due to a rewrite.
- New GitBook documentation.
- No longer working on a GUI version - not enough time to work on two different versions, tricky to implement in a GUI format, not cross-platform, and more confusing for the user downloading the software. More detail can be found here.