A utility for deterministically generating ssh keypairs. PROOF OF CONCEPT ONLY.
Each keypair is generated by hashing together a "seed" or "master key" (should be at least 32 bytes, randomly generated, and kept secret) and a unique "handle" (using the same handle will result in the same keypair, but the handle does not need to be kept secret); the resulting SHA256 hash is used as the input for generating an Ed25519 keypair.
This allows the creation of a large number of unique keypairs without having to actually manage the keypairs individually. This allows for, say, using a different keypair for every host you need to log into, thus preventing someone from correlating different user accounts on different hosts by the public keys in authorized_keys.
This proof of concept implementation just generates one keypair at a time; ideally the keypairs would be generated on demand, perhaps by an SSH agent implementation (the key generation step should only take a few milliseconds).
Note that while Ed25519 allows for using any 32-byte input to generate a keypair, making this implementation trivial, implementing a similar scheme for other key types is probably possible in some cases (eg. ECDSA), and infeasible in others (DSA/RSA, probably).
You will need ghc and cabal, as well as the libsodium development files; on
libsodium-dev packages are what you need.
$ git clone https://github.com/mithrandi/ssh-key-generator.git $ cd ssh-key-generator $ cabal sandbox init $ cabal install --only-dependencies $ head -c 32 /dev/urandom > seed $ cabal run ssh-key-generator -- --seed ./seed --mode raw --handle HIMOM --output ./id_ed25519 $ ssh-keygen -y -f ./id_ed25519
./seed is the master key,
HIMOM is the key handle, and
the output file into which the private key will be placed.
ssh-keygen is then
invoked to print the public key out.
There are three modes available:
- raw: Use the seed as is; must be at least 32 bytes long, and must have at least that much entropy in it to avoid weaker-than-expected keys.
- generate: Same as raw, except that a new seed will be generated using an appropriate platform-specific mechanism. The program will try not to overwrite an existing seed file.
- key: Use an existing Ed25519 SSH private key. Only the seed of the key will be used, rather than the whole key file data, so changes in the metadata will not affect generation.