Backup and restore SSH private keys using memorizable seed phrases.
Use your fave package manager:
# macOS or Linux
brew install charmbracelet/tap/melt
# Arch Linux (btw)
yay -S melt-bin
# Windows (with Scoop)
scoop install melt
Or download a pre-compiled binary or package from the releases page.
Or just build it yourself (requires Go 1.17+):
git clone https://github.com/charmbracelet/melt.git
go build ./cmd/melt/
The CLI usage looks like the following:
# Generate a seed phrase from an SSH key
# Rebuild the key from the seed phrase
melt restore ./my-key --seed "seed phrase"
You can also pipe to and from a file:
melt ~/.ssh/id_ed25519 > words
melt restore ./recovered_id_ed25519 < words
How it Works
It all comes down to the private key seed:
Ed25519 keys start life as a 32-byte (256-bit) uniformly random binary seed (e.g. the output of SHA256 on some random input). The seed is then hashed using SHA512, which gets you 64 bytes (512 bits), which is then split into a “left half” (the first 32 bytes) and a “right half”. The left half is massaged into a curve25519 private scalar “a” by setting and clearing a few high/low-order bits. The pubkey is generated by multiplying this secret scalar by “B” (the generator), which yields a 32-byte/256-bit group element “A”.1
Knowing that, we open the key and extract its seed, and use it as entropy for the bip39 algorithm, which states:
The mnemonic must encode entropy in a multiple of 32 bits. With more entropy security is improved but the sentence length increases. We refer to the initial entropy length as ENT. The allowed size of ENT is 128-256 bits.2
Doing that, we get the mnemonic set of words back.
To restore, we:
- get the entropy from the mnemonic
- the entropy is effectively the key seed, so we use it to create a SSH key pair
- the key is effectively the same that was backup up, as the key is the same. You can verify the keys by checking the public key fingerprint, which should be the same in the original and restored key.
- At this time, only
ed25519keys are supported.
- If your public key has a memo (usually the user@host in which it was generated), it'll be lost. That info (or any other) can be added to the public key manually later, as it's effectively not used for signing/verifying.
- Some bytes of your private key might change, due to their random block. The key is effectively the same though.
We’d love to hear your thoughts on this project. Feel free to drop us a note!
Part of Charm.
Charm热爱开源 • Charm loves open source