It turns out that MacOS Tahoe can generate and use secure-enclave backed SSH keys! This replaces projects like https://github.com/maxgoedjen/secretive
There is a shared library /usr/lib/ssh-keychain.dylib that traditionally has been used to add smartcard support
to ssh by implementing PKCS11Provider interface. However since recently it also implements SecurityKeyProivder
which supports loading keys directly from the secure enclave! SecurityKeyProvider is what is normally used to talk to FIDO2 devices (e.g. libfido2 can be used to talk to your Yubikey). However you can now use it to talk to your Secure Enclave instead!
recording.mov
See man sc_auth and man ssh-keychain for all the options
To create a Secure Enclave backed key that requires biometrics, run the following command and press TouchID:
% sc_auth create-ctk-identity -l ssh -k p-256-ne -t bio
You can confirm that the key was create with the list-ctk-identities command:
arian@Mac ssh-keychain % sc_auth list-ctk-identities
Key Type Public Key Hash Prot Label Common Name Email Address Valid To Valid
p-256-ne A71277F0BC5825A7B3576D014F31282A866EF3BC bio ssh ssh 23.11.26, 17:09 YES
It also supports listing the ssh key fingerprints instead:
% sc_auth list-ctk-identities -t ssh
Key Type Public Key Hash Prot Label Common Name Email Address Valid To Valid
p-256-ne SHA256:vs4ByYo+T9M3V8iiDYONMSvx2k5Fj2ujVBWt1j6yzis bio ssh ssh 23.11.26, 17:09 YES
Keys can be deleted with
% sc_auth delete-ctk-identity -h <Public Key Hash>
You can "download" the public / private keypair from the secure enclave using the following command:
% ssh-keygen -w /usr/lib/ssh-keychain.dylib -K -N ""
Enter PIN for authenticator:
You may need to touch your authenticator to authorize key download.
Saved ECDSA-SK key to id_ecdsa_sk_rk
% cat id_ecdsa_sk_rk.pub
[email protected] AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBKiHAiAZhcsZ95n85dkNGs9GnbDt0aNOia2gnuknYV2wKL3y0u+d3QrE9cFkmWXIymHZMglL+uJA+6mShY8SeykAAAAEc3NoOg== ssh:
You can just use the empty string for PIN. For some reason openssh always asks for
it even if the authenticator in question does not use a PIN but a biometric.
Note that the "private" key here is just a reference to the FIDO credential. It does
not contain any secret key material. Hence I'm specifiyng -N "" to skip an encryption
passphrase.
Now if you copy this public key to your authorized keys file, it should work!
% ssh-copy-id -i id_ecdsa_sk_rk localhost
% ssh -o SecurityKeyProvider=/usr/lib/ssh-keychain.dylib localhost
Instead of downloading the public/private keypair to a file you can also directly
make the keys available to ssh-agent. For this you can use the following command:
% ssh-add -K -S /usr/lib/ssh-keychain.dylib
Enter PIN for authenticator:
Resident identity added: ECDSA-SK SHA256:vs4ByYo+T9M3V8iiDYONMSvx2k5Fj2ujVBWt1j6yzis
% ssh-add -L
[email protected] AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBKiHAiAZhcsZ95n85dkNGs9GnbDt0aNOia2gnuknYV2wKL3y0u+d3QrE9cFkmWXIymHZMglL+uJA+6mShY8SeykAAAAEc3NoOg==
% ssh-copy-id localhost
% ssh -o SecurityKeyProvider=/usr/lib/ssh-keychain.dylib localhost
SecurityKeyProvider can be configured in .ssh/config but I recommend setting
export SSH_SK_PROVIDER=/usr/lib/ssh-keychain.dylib in your .zprofile instead as
that environment variable gets picked up by ssh, ssh-add and ssh-keygen.
This means you can just do:
ssh-add -K
ssh my-server
or
ssh-keygen -K
ssh -i id_ecdsa_rk_sk my-server
to ssh into your server