Secrez — a secrets manager in time of cryptocurrencies
Secrez is a CLI secret manager written in Node, which manages an encrypted file system and speeds up operations that are slow, or impossible, with traditional password managers.
I built Secrez during the quarantine, those days when I was not feeling inspired enough to either write my novel or work on some music. But I had the initial idea in 2017, and I wrote a first, rudimental version then. Let me tell you why and how.
In 2017 I was very active in the cryptocurrency world. As a consequence, I had tons of private keys, passwords, and mnemonic seeds. At that time, I was using a modified version of Passpack desktop, which was inadequate to manage this kind of data, like any other standard password manager.
If you use, for example, MyEtherWallet to create a new Ethereum wallet, before using it, it is imperative to back up the private key.
I am not using it now, and I don’t know if anything has changed, but in 2017 MyEtherWallet allowed you to export a Keystore/JSON file containing the private key. Since it was encrypted, you could have saved it as is, but for privacy reasons you would put it in your password manager anyway.
Assuming that you created a new entry in your password manager, to add the Keystore/JSON file, you had to:
- download the file
- open it with an editor
- copy the content
- paste it in the notes
- open the ~/Downloads folder
- delete the file
To restore an account, you had to:
- copy the JSON from the notes
- open a folder
- create a temporary file
- paste the JSON in the new file
- save the file as <something>.json
- import it in MyEtherWallet
- delete the temporary file
It doesn’t look very smart, does it?
A secrets manager for geeks?
Maybe. Let me talk a bit about the design choices.
The first design choice was about the type of app
Secrez was initially just for me. Since I love command-line tools, it was natural to go for a CLI application. As a consequence, it made sense to use commands that resemble Unix commands. For example, to list all the secrets in the current folder, you can run
ls
You will see an output identical to the one returned by ls in a Unix environment. To create a new file with a single line content, you can run
touch new-file -c "Some secret content"
But you can also use your default text editor running:
edit new-file -c
where the -c
is the alias for --create
. In general, you can see all the options of a command running
edit -h
and all the commands running
help
Here a screenshot, with some examples:
The second design choice was the structure:
an encrypted file system for the secrets, with the ability to move files between the standard OS and the encrypted OS. In the example above, I can import the Keystore/JSON file with a command like
import ~/Downloads/mew-export-2020–06–22T20_10_15.789Z.json -m
and export it with
export mew-export-2020–06–22T20_10_15.789Z.json -d 30
The first command would import the file, deleting the original one.
The second one would export the file, deleting it after 30 seconds.
One step instead of six or seven. Not bad 😉
The third design choice was about the data
There are two primary approaches to secret/password management:
- SaaS apps that save the data online (like LastPass)
- Desktop tools who keep data in the computer (like KeyPass)
An Online Password Manager requires that you trust the remote server. I founded Passpack in 2006, and I know very well how, at any moment, you can add a backdoor, and most likely, nobody will notice it. You can even set a backdoor for a specific user. If the FBI commands LastPass or 1Password to do it, they could be forced by law to do it.
You don’t believe so… Look at this:
A desktop tool is intrinsically more secure, but it is hard to use on more than one computer. The standard solution is to back up the database on Dropbox or Google Drive. Still, before using it, you must download the backup locally. This approach is prone to produce unfixable problems and cause data loss.
Secrez’s goal was to be as safe as KeyPass but available everywhere, like Lastpass.
To obtain this goal, Secrez assembles a few strategies:
- Any secret is a local file
- Any file is immutable
- Any change can be pulled/pushed to a remote repository
This way, you can distribute your data using Git and avoid conflicts because secret files are never modified. There are some exceptions, but they are related to rare actions (like adding a 2FA); in that case, you can be careful.
You can either create a private repo on GitHub, BitBucket, etc. or — much better — setting your own, self-hosted git server, as I do.
In the beginning I tried to use pass (which adopts a similar approach) but I hated its UX, and I uninstalled it after a few days of frustrations. If you like pass, you could give Secrez a try and let me know what do you think 🙃
Another choice to own your data, while having them available online, is to use Bitwarden. It is open-source, and you can install your own server. Still, it does not solve the issues with managing files.
The last one was about the algorithm
After many tests and an extended analysis of the alternatives, I decided to use TweetNaCl for the encryption because it manages symmetric and asymmetric encryption, and prepares a future where it will be possible to share data among users.
The structure
Secrez simulates a file system. The data is organized in datasets. Think of them as separate disks, similarly to /dev/disk1
and /dev/disk2
.
By default, Secrez generates two datasets: main
and trash
, but you can create more. The advantage of multiple datasets is mostly for people who have a lot of secrets to manage. If you have 2,000 (like me) and you put them all in the primary dataset, the system will probably become quite slow. The solution is to move data to separate datasets.
Never lose secrets
One of the primary goals of a secrets manager is to never lose any data. However, since in Secrez, only the most recent tree is read, some secrets could be in the folder and not been loaded. If this happens, Secrez decrypts the missing secrets, reads their positions from previous trees, and puts them back in the tree. If they are not in an older tree, it creates special folders starting from REC_
and puts the recovered files in there.
Make hard to perform brute-force attacks
Secrez uses crypto.pbkdf2
to iterate the password you choose when you initialize the system and generate a derived key, which is used to encrypt a random master key.
The number of iterations is your choice, and it is significant because you keep it for yourself. On my Macbook, a million iterations require less than a second. But if I forget that number, it would require ~100 hours to recover my own account, despite that I know the password, because the number of iterations modifies the salt used during the derivation process.
Let’s say that you set it to 638,276. What if someone who ignores the number of iterations wants to discover your password? The hacker could
- choose a phrase from a dictionary
- iterate the phrase between, let’s say, 1 and 1,000,000 times
- repeat the process for any new phrase
There are many ways to optimize this process, but, even if the hacker uses a high-speed computer that requires only 1 hour to verify the single word, testing 1000 words could take more than one month. If your choice is just a bit uncommon, discovering it could require years.
And, of course, if you had chosen 2,013,900 iterations, the attack above would be a full waste of time.
BTW, your password must be a good one. But you get the point.
To simplify our lives, Secrez can save the number of iterations locally, in a git-ignored file. This is acceptable because the primary goal was to block whoever gets access to the private repo where you back up the data. If you decide to set up a private repo on GitHub, how can you be sure that some employee does not clone it? With a secret iteration number, you can sleep like a baby.
Getting started with Secrez
Secrez is an open-source application built in Node. You can install it with
npm i -g secrez
In the future, I plan to add binaries that you could install with brew or apt-get.
To run secrez, in the terminal, run
secrez
By default, Secrez puts the data in ~/.secrez
. If you prefer to use a different folder, and save locally the number of the iterations, you can call something like
secrez -sc ~/Documents/personal/secrez
Importing from other secrets managers
If you already use a password manager, you can import that data.
Suppose you have exported your password in a CSV file name export.csv like this:
Path,Username,Email,Password,Website,Notes,Tags
twitter/nick1,nick1,nick1@example.com,938eyehddu373,,,twitter
facebook/me,,fb@example.com,926734YYY,,"Some note",facebook facebook/second,jerry,jerry@example.com,s8s8s87e78ew,,,,facebook
A field named path is mandatory because Secrez needs to know where to put the file. The path is supposed to be relative, allowing you to import it in your favorite folder. Let’s say you like to expand the imported data in the current folder (that you can check with pwd
), and like to preserve the tags as actual tags, you could call
import export.csv -e / -t
If your password manager does not export in CSV format, you have to reformat your data. In the future, I hope that there will be scripts to pre-format the data to import them in Secrez.
Two-factor Authentication
Secrez uses external scripts in Python, based on Python-Fido2
by Yubiko, to support 2FA. It's compatible with any Fido2 authenticator device implementing the hmac-secret extension.
To register my Solo — by Solokeys — I can call:
conf - fido2 -r solo
When you activate the first fido2 key, Secrez asks if you also want to generate an emergency recovery code, which lets you to recover the account if all the registered keys are lost.
Aliases — where the fun comes 🤪
Suppose that you have a card for your bank and want to log into it. You could copy email and password to the clipboard to paste them in the browser. Suppose that you expect to be able in 4 seconds to move from the terminal to the browser, you could run the command:
copy bank.yml -f email password -d 4 2
This will copy the email field and give you 4 seconds to paste it in the browser. After it will emit a beep and you have 2 seconds to paste the password. It sounds quite useful, but it can be better.
If you use that login often, you could like to create an alias for it with:
alias b -c "copy bank.yml -f email password -d 4 2
Next time, you can just type
b
and press enter to execute that command.
It looks great, right? Well, it can be even better.
Let’s say that you are using a 2FA app (like Google Authenticator) to connect to a website, for example, GitHub. Suppose that you have a file github.yml
with a field totp
which is the secret that GitHub gave you when you activated the 2FA. You could execute
totp github.yml
to generate a TOTP token for GitHub. The token will be shown and copied in the clipboard. Now, you can create an alias like this
alias G -c "copy github.yml -f username password -d 4 2 --wait && totp github.yml"
Can you guess what this will do?
- It copies the username in the clipboard;
- it waits 5 seconds, emits a beep and copies the password;
- it waits 3 seconds, emits a beep and copies the TOTP token and keep it in the clipboard.
You can also use parameters in aliases and create a macro like
alias M -c "copy $1 -f username password -d 4 2 --wait && totp $1"
and call it with
M github.yml
It is fantastic, isn’t it?
BTW, using a TOTP factor in Secrez is a bit of a contradiction because you are converting a second factor (something that you have) in a first factor (something that you know). So, use this feature only when it makes sense.
Final thoughts
Secrez does not want to compete with standard password managers. So, don’t expect in the future to have “form filling” and stuff like that. However, it is open-source and it’d be awesome if you’d like to add a GUI or a mobile app.
The best way to know more about Secrez is to follow its GitHub repo at
https://github.com/secrez/secrez
starting from reading the README, which is updated anytime there is something new.
Back up, back up, back up
An invisible bug can be somewhere, and you could lose some data.
A back up is a lifesaver!
My suggestion is to use Git (or Mercurial, CVS, whatever).
It will allow you to reverse to previous commits in case you lose any data. If you don’t want to use a versioning system, at least do a local backup every time that everything looks fine. You could use rsync
for it. If you create a backup folder called ~/.secrez-bak
, to sync the data between the two folders, just run:
rsync -avh ~/.secrez/ ~/.secrez-bak/ - delete
A quick demo?
If you like this post, please 👏 and share it!
This post has been also published at https://room29.art/secrez-a-secrets-manager-in-time-of-cryptocurrencies/.