Introduction
Kestrel is a command-line file encryption application that makes it easy to encrypt files for yourself or for friends.
Kestrel features modern algorithms with strong security and privacy guarantees.
Supports Linux, macOS, and Windows
Installation
Getting Started
Installation
Download a release
Pick the file for your operating system.
Kestrel supports
- Linux on x86-64, arm64
- macOS on Apple Silicon (arm64), Intel
- Windows on x64 with a traditional installer or portable install.
Linux
Debian / Ubuntu / .deb
Install the .deb package. Example:
sudo apt install ./kestrel_0.10.0-1_amd64.deb
Bash completion and man pages are included and automatically installed.
Uninstall
sudo apt remove kestrel
Fedora / .rpm
Install the .rpm package. Example:
sudo dnf install ./kestrel-0.10.0-1.fc36.x86_64.rpm
Bash completion and man pages are included and automatically installed.
Uninstall
sudo dnf remove kestrel
Arch Linux
kestrel is available on the AUR
Follow the normal installation procedure for AUR packages.
Static Binary
Extract the .tar.gz
. The binary can be run from anywhere.
Example to place the binary on your $PATH
:
sudo cp kestrel /usr/local/bin
kestrel --version
macOS
Homebrew
brew tap finfet/kestrel
brew install kestrel-cli
kestrel --version
Bash completion and man pages are included and automatically installed.
Static binary
Extract the .tar.gz
. The binary can be run from anywhere.
You may need to remove the macOS quarantine attribute that is added to files downloaded from the internet.
xattr -d com.apple.quarantine kestrel
Example to place the binary on your $PATH
:
sudo cp kestrel /usr/local/bin/
Uninstall
Remove binary
brew remove kestrel-cli
Uninstall tap
brew untap finfet/kestrel
Windows
Windows Installer
Follow the instructions on the installer. You may need to click through the SmartScreen warning.
After installation, Kestrel can be used from powershell or command prompt
using the command kestrel
.
Portable Install
Unzip the archive. kestrel.exe
can be run from any location that you
would like.
SHA-256 Checksums
It's a good idea to make sure that what you downloaded matches the expected file hash.
The SHA-256 hashes of the release can be found in the file SHA256SUMS.txt
Linux
Use sha256sum <archive-name.tar.gz>
macOS
Use shasum -a 256 <archive-name.tar.gz>
Windows Powershell
Use Get-FileHash <the-archive.zip>
Getting Started
Installation
Make sure that you have the application installed. See installation for more.
Generate a new key pair
Follow the prompts to give the key a name, and encrypt it with the password you choose.
The name can be anything that helps you remember your key. A name, nickname, or email are good ideas. In the example Alice is generating a key for herself.
kestrel key generate -o keyring.txt
The result is a file that looks like this:
[Key]
Name = alice
PublicKey = mI4mKm85lXzbYdHhDW7hX8yWDIuSwRuzjATP/w4mZxwm+Dck
PrivateKey = AAHr9qFFlOx1ujtQg8bQ8I5GTzwWmBjRU8Cf0VAK2CuRKNNlsW4XWCu2GEzFQuqNb1UrkLev7+Qn9OgS5xwVOR3j
This is an example key. Do not use this. Make sure to generate your own.
A [Key]
has three properties: Name
, PublicKey
, PrivateKey
.
Name
is a nickname for a PublicKey
. It's short so that you don't have to
type the PublicKey
each time. You'll use Name
to refer to specific public
keys, so each name should be something unique that reminds you of the person
that owns that key. Remember that you are also a person with a PublicKey
so
you can encrypt files for yourself.
PublicKey
is the public identifier for a key. Your friends will use this
public key to send you files. You can post the PublicKey
anywhere. Post it
on social media, e-mail it to your friends, whatever works. Just make sure
that they have a good copy of your public key.
PrivateKey
must be kept secret. Never share it. To be able to decrypt
files that are sent to you, you'll need to know the private key
string and the password used to unlock it. If you lose your private key you
will no longer be able to decrypt files. Keep a backup of the private key
somewhere safe.
Encrypt a file using a key
Let's encrypt an example file. Alice is using a file called example.txt
. You
can use any file that you want. Grab a file from your computer and try it out.
Here Alice is encrypting a file to the key alice
and from the key alice
.
She is encrypting the file to herself. This is a great way to keep backups secure from online storage providers.
When encrypting a file, think of it like addressing a letter. The destination
--to
is a public key with a name. And the --from
is the sender's key.
kestrel encrypt example.txt --to alice --from alice -k keyring.txt
This results in a file called example.txt.ktl
that only Alice can read
and decrypt.
Decrypt a file
To decrypt Alice uses
kestrel decrypt example.txt.ktl --to alice -k keyring.txt
The result is the decrypted example.txt that Alice can view. For the --to
option, Alice chose her key, because she knows that the key was sent to her.
Upon successful decryption, Alice she can see that the file was sent from
the alice
key.
To decrypt a file, you'll need to know the key that the file was sent to. If you only have one key pair, this will always be your only key. However, if you have multiple keys, like for work and school, when trying to decrypt the file you'll need to know if you should use the work key or the school key.
Adding a Public Key
Alice just met Bob and got Bob's public key from social media.
Bob's public key is
g4Yms3Wq9stLOCzCAA7LgFnoDahpKZIzvnqZFO4DD2kmfYpf
Alice can add Bob's key by modifying keyring.txt
and adding another [Key]
section.
[Key]
Name = bob
PublicKey = g4Yms3Wq9stLOCzCAA7LgFnoDahpKZIzvnqZFO4DD2kmfYpf
Name can be anything that helps Alice identify Bob.
Now Alice can encrypt a file for Bob using his key.
kestrel encrypt example.txt --to bob --from alice -k keyring.txt
The result is a file example.txt.ktl
that only Bob will be able to decrypt.
Alice can then send this file to Bob through e-mail or some other means.
Default Keyring
Instead of having to use the -k
option each time in order to specify the
location of the list of keys, you can set a default keyring that will be
used automatically.
To do this, set the environment variable KESTREL_KEYRING
to the location
of the key file that you would like to use.
Password Encryption
Instead of using Public Keys, you can also encrypt and decrypt files using passwords.
kestrel password encrypt example.txt
kestrel password decrypt example.txt.ktl
Key Management
Public and private keys are simple Base64 strings. Put your public key somewhere that your friends will have access to. Post it to social media, email it out, whatever works.
When you want to encrypt a file to a friend, just copy their public key and add it to your list of keys.
Private keys are always encrypted with your password. Make sure to choose a strong password. Although the private key is encrypted, it's still a good idea to keep it hidden.
As long as you have access to your private key and the password used to unlock it, you'll be able to access your data. However, if you lose access to the private key and/or password, you won't be able to decrypt any files sent to that key.
You can change the password of a private key
kestrel key change-pass <BASE64-PRIVATE-KEY>
You can view the public key for a private key
kestrel key extract-pub <BASE64-PUBLIC-KEY>
Usage Help
View all of the usage options
kestrel --help
Security Guarantees
If decryption of a file is successful, you know for certain that the file hasn't been tampered with and that it came from a specific known key.
See more in security information
Security Information
Overview
Kestrel uses a simple combination of the Noise Protocol and a chunked file encryption scheme.
The noise protocol (Noise_X_25519_ChaChaPoly_SHA256) is used to encrypt a payload key. This payload key is then used for ChaCha20-Poly1305 file encryption. Files are split into encrypted and authenticated chunks, ensuring that unauthenticated data is never written to disk.
Users can also use a password instead of public keys. This password is used with scrypt to derive a symmetric key for file encryption.
Public Key Encryption
The X pattern of a noise protocol handshake is used to perform public key authenticated encryption between sender and recipient.
In order to send a message, senders are required to obtain a legitimate copy of the recipient's public key.
Security Properties
Overview
- When you successfully decrypt a file, you know that the file hasn't been modified and that it came from a specific, known public key.
- Deniability. If you send a message and your recipient reveals it and tries to claim that you sent it, you can deny it because the recipient has the ability to forge received messages.
- If your private key gets compromised later, the attacker can't read the messages that you've sent. The only way to decrypt the messages is to compromise your recipient's private key.
- If your private key gets compromised, the attacker can pretend to be you. You need to get a new key pair and be able to communicate the new public key to your contacts.
- Messages can be replayed. Replay prevention is out of scope for this application. However, replay is considered benign in this context. Imagine sending your encrypted tax files to an accountant. The attacker can resend your encrypted file to the accountant, but the accountant will end up with a benign, redundant copy.
- The encryption is meant to work as you would expect it to. If you get a file, you know who it came from, and that it hasn't been read or tampered with. When you send a file, only the person that you sent it to can read it.
Guarantees from the noise protocol
Each payload is assigned a "source" property regarding the degree of authentication of the sender provided to the recipient, and a "destination" property regarding the degree of confidentiality provided to the sender.
Source properties
Sender authentication vulnerable to key-compromise impersonation (KCI). The sender authentication is based on a static-static DH ("ss") involving both parties' static key pairs. If the recipient's long-term private key has been compromised, this authentication can be forged.
Destination Properties
Encryption to a known recipient, forward secrecy for sender compromise only, vulnerable to replay. This payload is encrypted based only on DHs involving the recipient's static key pair. If the recipient's static private key is compromised, even at a later date, this payload can be decrypted. This message can also be replayed, since there's no ephemeral contribution from the recipient.
Encryption Steps
- A fresh 256 bit symmetric key is generated from a CSPRNG. This is the payload key.
- A noise handshake is performed between the sender and recipient with the payload key included as the noise payload. The result is a noise handshake message that includes the encrypted payload key and the encrypted sender public key.
- The plaintext is encrypted using the payload key and the chunked encryption format.
Decryption Steps
- The recipient must choose to decrypt using the same key that the sender chose as the recipient key. Because the ciphertext contains no identifying information from either the sender or recipient, the recipient must choose the correct key pair from which to attempt decryption. If the recipient has, for example, a work key pair, and a personal key pair, the recipient must know to decrypt with either the work key or the personal key. Obviously decryption could be attempted with both keys if the recipient is unsure.
- The recipient decrypts the noise handshake message. If successful, this results in the decrypted payload key and sender's public key.
- The ciphertext is decrypted using the payload key and the chunked encryption format. The sender's public key is displayed upon successful decryption.
Password Encryption
Scrypt is used to derive a symmetric key from a password which is then used with the chunked file encryption format.
Security Properties
Files are encrypted and authenticated. After a successful decryption, you can be certain that the file was not modified and that it came from the person in possession of the shared password.
Encryption and Decryption Steps
- A symmetric key is derived from a password using the scrypt parameters N = 15, r = 8, and p = 1.
- The file is encrypted or decrypted using the derived key and the chunked encryption format.
Chunked File Format
Files may be too large to fit entirely into memory, so they are split into into encrypted and authenticated chunks.
Each chunk has a chunk number starting from zero and incrementing sequentially (0, 1, 2, 3, ...).
The chunk number is also used as the nonce for the encryption function. Keys are fresh for each message ensure that the nonce does not repeat.
Chunks are 65,536 bytes (64k) in size.
The last chunk has an authenticated last chunk indicator signifying that this is the last chunk in the message. The chunk number MUST increase sequentially and MUST contain only a single last chunk indicator.
This design ensures that chunks in a message CANNOT be re-ordered, modified, removed, duplicated, or truncated.
Messages CANNOT be modified or truncated without detection.