If I understand correctly, this means you can't back up the private key, correct? It's in the Secure Enclave, so if you lose your laptop, you also lose the key? Since it looks like export only really exports the public key not the private one?
Probably not the worst thing, you most likely have another way to get into the remote machine, or an admin who can reset you, but still feels like a hole.
Or am I missing something?
ps. It amuses me that my Mac won't let me type Secure Enclave without automatically capitalizing it.
Edit: I understand good security is having multiple keys, I was simply asking if this one can be backed up. OP answered below and is updating their webpage accordingly.
Check out `man sc_auth`. There's also an exportable variant where the private key is encrypted using the secure enclave as opposed to generated on the secure enclave:
% sc_auth create-ctk-identity -l ssh-exportable -k p-256 -t bio
% sc_auth list-ctk-identities
p-256 A581E5404ED157C4C73FFDBDFC1339E0D873FCAE bio ssh-exportable ssh-exportable 23.11.26, 19:50 YES
% sc_auth export-ctk-identity -h A581E5404ED157C4C73FFDBDFC1339E0D873FCAE -f ssh-exportable.pem
Enter a password which will be used to protect the exported items:
Verify password:
You can then re-import it on another device
% sc_auth import-ctk-identities -f ssh-exportable.pem.p12 -t bio
Enter PKCS12 file password:
Is there a way to import an existing (compatible) key and still mark it as non-exportable?
That seems more useful for the SSH key scenario: Generate a key in memory and back it up to offline storage once, and otherwise only use it in a way totally non-exportable by any malware.
This sentence
> The exportable private key is encrypted with Elliptic Curve Encryption Standard Variable IVX963 algorithm which is backed by a Secure Enclave key.
makes it sound like exportable keys might inherently not be Secure Enclave resident in Apple's implementation, which would be unfortunate, as anything else can still be accessed by malware with kernel-level privileges.
(GPG, and I believe also PIV, allow importing externally-generated keys without necessarily marking them exportable; they'll just, correctly, lack any attestation statement about having been generated in secure hardware.)
Can you explain which keys in the secure enclave make this work because it has at least two keysets: a public-private keypair locked to the root key Apple instantiated in hardware as fused links in the chip and so in theory this could include private keys common to all the devices in this chipset generation, and the locally generated unique keys which are tied to this specific device.
Using the first pair or products of the first pair, means in principle your private key is protected by the goodwill of Apple only: if you allow it to exist at rest in a form only this shroud protects, then Apple can read the private key unless the symmetric algorithm used to "unlock this private key with your password" is a good one, and you chose a password wisely. I haven't used the function so I can't comment how they constrain what you put in as a personal lock on these blobs.
You're not really supposed to 'export' keys. Any time you move a key you risk exposing it. The idea of PKI is that only public keys move, the private key stays in one place, ideally never seen.
I've been in the security space for 25 years, and understand the theory of PKI. But I've also been in the ops space for 30 years, and understand that if you don't balance security theory with operational practice, critical business functions can fail.
Ideally yes, the private key is never seen. In reality, it needs to be backed up in a secure place so it can be restored in the event of a failure.
It's much safer to export a key one time and import it into a new machine, or store it in a secure backup, than to keep it just hanging out on disk for eternity, and potentially get scooped up by whatever malware happens to run on your machine.
Strictly speaking people should be using multiple keys so if a device is lost/stolen, you're not left high and dry. Ideally one per device, especially if they don't support some kind of secure enclave.
I keep one in a yubikey protected by a PIN that sits in a safety deposit box, too. This way if I have my laptop, phone, and day-to-day yubikey is a house that suddenly burns down, I'm still ok.
Yeah, that is why you should not [always (depends on your use case)] generate it on a YubiKey.
You need to have:
- an offline master private key backup (air-gapped)
- primary YubiKey (daily use)
- backup YubiKey (locked away)
- revocation certificate (separate storage) (it is your kill-switch)
Having a second YubiKey enrolled is the standard practice.
What people do wrong is:
- They generate directly on YubiKey
- They only use one device
- They do not create a revocation certificate
- They have no offline backups
You generate your GPG keys on a secured system, load the subkeys (not the master because it is not used for daily cryptography) into the YubiKeys, and then remove the secret keys from this system where you generated the keys.
Which makes yubikey impossible to use with geographically distributed backups. You need the backup available at all times for when you want to register with any new service.
This is why you should use a device which allows exporting the seed, like e.g. multi purpose hardware crypto wallets.
Yes, that's the point, indeed. One key per device, impossible to extract, so you need to break into the device to use the key.
If you want to maintain backup access, you can use an SSH CA to sign your public SSH keys, then keep the private keys on your device. If you keep the CA keys safe (i.e. physically safe on a flash drive), this means you can even add new keys after you lose all your devices.
This way, you only need to trust your one CA on your servers (so you don't need to copy 20 public keys around for every server).
Plus, if you're setting up a (separate) SSH CA, you can also sign servers' host keys, so you don't need to rely on TOFU to prevent MITM attacks, if that's something you care about.
This is the fundamental paradox of hardware secured keys. Basic ones generate the private key inside and never let it be exported. This allows you to be very sure it won't ever leak but also doesn't let you back it up. Higher end Hardware Security Modules allow the private key to be exported but only when encrypted with the valid public key of a destination HSM.
> If I understand correctly, this means you can't back up the private key, correct? It's in the Secure Enclave, so if you lose your laptop, you also lose the key?
In a business environment, that's what you want. The key is then burned, and you ask your coworkers (who still have access) to remove the old key and store your new one on the servers.
I had being using krypton, with the private key being on my iPhone, and am now using secretive. Never had much of an issue with not having access to my private key. We made rolling out public keys to the servers very easy by using the gitlab key file. So when I get a new Macbook I'd just need to create a new key and upload it to gitlab. We have multiple devops that can run the playbook to roll it out to the servers. And if they have a new Macbook I roll it out for them. And we don't have that many Macbook upgrades anyway.
Ok I wished for this kind of feature for years. I started using a yubikey with an ssh key via gpg ssh-agent in 2018 or 2019. When resident ssh keys came around I switched over to FIDO2 based keys on my yubikey. The main issue with both was the fact that the default ssh setup wasn’t working anymore. One needs extra configs and more commands to get to the public key etc. Yubikey’s are great but block an USB port. And then there is the age old question for me: One SSH key per User for all services? One key per machine for all services? Or one key per service?
This year I started to play around with the 1Password ssh-agent feature (bit warden has it as well as far as I know)
If you're ok with allowing all your keys being listed in the agent this works pretty easy out of the box.
I never liked the fact that the default recommended way to use ssh is to use an agent that just has multiple keys which can be tested one after another and in most cases stay unlocked there after first use for the rest of the session.
I configured around to make sure that I explicitly use one key for one specific service. But that is sadly extra configuration etc etc.
I believe that in 1Passwd you can define / preselect a key per host now. So you can pinpoint key -> host. Some hosts have firewall rules that will block after X attempts were X might be low.
However the agent still has access to all your keys, obviously.
Ah cool. I worked around by storing the public keys in my dot repo and use the identity file ssh config option for said host. Great if I don’t have to do this anymore.
Next level config madness: Use different ssh keys per GitHub org ;).
side note: It's interesting that the `sc_auth` CLI tool to create the SSH key, is just a bash script! It seems truly ancient, and has comments referencing mac OS Tiger (20+ years old) and non-existent files from old macOS. It calls out to '/System/Library/Frameworks/CryptoTokenKit.framework/ctkcard' (not on PATH) to actually create the ssh key.
It's a golang library that abstracts usage of ssh keys backed by hardware on all sorts of devices - mostly designed for laptops, but supports Linux, Windows and MacOs
If you're willing to go a bit further you can also do GPG signing with ECDSA, though it requires a patched GPG due to bugs and a patched SSH agent that allows raw signing. We have a packaged version with a macOS UI [0], but the same backend [1] works on Linux using the tpm via PKCS#11.
We have a blog post on this, but I guess it was never made public, but the only difference between GPG and SSH is the way in which keys and signatures are wrapped and listed through the various layers -- it's all just fundamentally ECDSA with a named curve.
I've been using Secretive for years, and prefer it to all the physical key/card based systems I've tried to get going over the years. I know exactly when my SSH key is used for any operation, because I need to hit a button or do a fingerprint scan. I can keep ssh-agent tunnels to remote boxes so that I can sign git commits remotely without having to worry about a rogue system getting complete access to key ops without me knowing what's going on.
However the Tahoe version of secretive is buggy and frequently locks up on initial key op requests. I don't have the bandwidth to debug it and file a bug report, and honesty I'm not sure I want to relearn all that knowledge of SSH to figure it out.
I think the smart card SSH UX is worse than secretive's, IIRC my past pain, but if it is reliable, worth a shot.
> I can keep ssh-agent tunnels to remote boxes so that I can sign git commits remotely without having to worry about a rogue system getting complete access to key ops without me knowing what's going on.
I also really like secretive, but at least this part is not exclusive to it; OpenSSH's `ssh-agent` and `ssh-add` have long supported confirmation of each private key use with `ssh-askpass` (although it unfortunately can't distinguish between remote and local key uses).
The key itself appears to have no validity period, the validity period is only for the certificate made for the key. Maybe you could create a CSR for the key/identity and then sign it with your own CA (or self-sign with openssl) for whatever validity period you like. Then `sc_auth import-ctk-certificate`.
This seems really cool. I use Secretive and would like to switch to this native solution. The one thing holding me back is that I like that Secretive allows you to create keys that don't require TouchID, yet still notifies you when they are used.
I use an external keyboard, so reaching for the fingerprint reader isn't as easy as it would be if I just used the internal keyboard. Fine, ControlMaster is a good compromise. Except when git signing (every commit) is a requirement, you have to touch the reader every, single, time. That's fine when making routine commits, not so when rebasing. Ideally, I could tell the SecureEnclave to notify me, but don't require biometrics for the next 30 seconds or so, but since that's not a thing, that I'm aware of, I'd at least like to know when my git signing key is being used.
This isn't such a great idea for personal SSH or GPG keys that should be locked away in physical hardware thing that need to be moved to other devices/machines. What security processors are great for is corporate machine, system/service, and user key management IdM/MDM processes that need secret storage.
Furthermore, with portable devices like Yubikey it's possible to create a master Certify-only GPG key where the sub Signature/Encryption/Authentication-subkeys live on the Yubikey. The encrypted C private key part with the S/E/A stubs still needs to be backed-up to some durable, versioned storage that isn't tied to one device.
Finally, use GPG for SSH. And definely avoid file-based SSH local private key management for wherever possible for anything substantial because it doesn't scale well.
> This isn't such a great idea for personal SSH or GPG keys that should be locked away in physical hardware thing that need to be moved to other devices/machines
I would change this: it’s great for personal usage BUT you should always use n>1 keys to avoid being locked out. For example, using the Secure Enclave for your daily use is fine but you’d want to have, say, a FIDO2 hardware key setup so if your laptop fails or is reset you can get into anything where you use that key.
How can I get such a key into my iPhone too, so that I can sign emails and file and such with the same private key when I'm on my phone, and my public key is valid for all such operations ? Will iCloud take care of that ? And then I want it all usable from my (multiple) email clients...
What you're thinking of are Passkeys. Which are synced. Somebody would have to write an SecurityKeyProvider that talks to the Passkey API instead.
Actually I don't think it's completely impossible. The only thing is that passkeys are origin-bound. They belong to a specific AppBundle ID or domain name. If say Secretive would add passkey support then that specific public/private keypair can't be used by another app. Though it does sync across instances of the app across devices.
Clearly I'm hazy on this stuff. But if I can export the private key from my Mac, is there any use for it on my iPhone, and any way to get it in there ?
it describes how to use your YubiKeys (please always use at least two, so that you have a backup) for GnuPG keys and SSH.
I've been using this setup since 2018 and it is brilliant. I know GnuPG is not in fashion these days, but thanks to this setup I have SSH logins using YubiKeys, encrypted backups using GnuPG, and 2-factor authentication for a number of sites that support Webauthn. All with backup keys, which is IMPORTANT: do not get locked into using a single device, because sooner or later you will lose that device or it will suddenly die.
I've heard people make the point before that EdDSA is not great for secure enclaves due to being suspictable to Fault Attacks which could lead to (partial) key extraction
I don't trust the NIST curves: they were generated in a dubious way which has been written about extensively elsewhere (the coefficients for P-256 were generated by hashing the unexplained seed c49d360886e704936a6678e1139d26b7819f7e90). I always avoid them unless I have to use them. It makes me sad when hardware forces me to use them.
> I've heard people make the point before that EdDSA is not great for secure enclaves due to being suspictable to Fault Attacks which could lead to (partial) key extraction
Huh, got a link? My understanding is that eddsa is better with respect to side channels in every way, that was part of the intent of it's design. I've worked with crypto hardware which supports it.
Time to up my game and finish adding new features to KeyMux, which supports enclave keys for SSH, SSL, and PGP, including in mixed-use scenarios, such as secure enclave-backed SSL peer authentication to a Vault server for SSH authentication with a non-exportable Vault private key: https://keymux.com/ (https://apps.apple.com/us/app/keymux/id6448807557)
Oh, this is neat! I wonder if apple just added support for the secure enclave as a provider or if this might help fix the bad experience of yubikeys on the mac. Last time I tried it, the distributed ssh and ssh-agent didn't play well with security keys
Unfortunately I've found that not every source management tool understands SSH signatures and using them may have your commits end up being shown as signed by an untrusted key.
On Linux, GPG supports TPM2, but I'm not sure if that also works on macOS.
Some Fido2 keys like the YubiKey and Nitrokeys support PGP keys as well. Works pretty nice as well and has the added bonus of your key not being tied to a pice of hardware that is as likely to break like a laptop (or be upgraded on a semi-regular basis)
You can (mis)use ssh keys for git signing, but GPG on gpg-card and S/MIME on PIV card are the two standards and their respective hardware implementations (for signing keys in general.)
Probably for the same reason that OpenSSH's `sk` implementation also still needs a private key file (even for the "resident key" option): You need to be able to point OpenSSH's various tools to something in an identity context, and that something traditionally is a private key file.
The article even mentions that it doesn't contain any sensitive data:
> Note that the "private" key here is just a reference to the FIDO credential. It does not contain any secret key material.
It's a slightly different story for non-resident `sk`-backed keys; these actually require the private key file since the hardware authenticator itself is (or at least can be) stateless. (It's still not a security risk if it ever leaks, but it's an availability risk if it's ever lost.)
Not sure if macOS's backing implementation is stateful or stateless (or some unfortunate hybrid of both; i.e., it might just store a stateful wrapped key in some system-level keychain in a way that intransparently breaks if the OS is ever reinstalled, but also doesn't allow querying an intact system for any existing credentials).
Fundamental services like DNS, which was designed as distributed going down was the cause last 2 outages and really need to think of alternatives methods to ensure resilience. Shift left, design better.
It's a total pain in the ass to try to have password encrypted gpg or ssh keys in mac. Nothing better that another way to make it even more painful and complicated, so that people will just store plain text keys to not be annoyed.
> It's a total pain in the ass to try to have password encrypted gpg or ssh keys in mac.
Who uses password encrypted keys anyway ? No exfiltration protection, and a sitting duck for unlimited automated password guessing attempts.
Pre-Tahoe people used Yubikeys or Secretive. But now this native tool is a better option than Secretive, even if Yubikeys still have their uses for the power-users.
With an ssh agent and time-bounded key expiration one can have very strong password on the key that is convenient to use.
Also password managers like 1password or Bitwarden support ssh-agent protocol so one can have a master password that protects both stored passwords and keys.
Edit: I'm not suggesting an ssh key with a passphrase (or password) is better than what the article suggests; I'm only saying that adding a passphrase (or password) to an ssh key at least buys time to address the situation while the attacker is trying to break the encryption on the stolen key.
I am anti-Mac in every way, but I do use passphrase protected ssh keys so if someone were to get a copy of my ssh key, they would have to be able to break the encryption to use the key. I see a lot of devs using blank passphrases on their ssh keys, smh.
> sitting duck for unlimited automated password guessing attempts.
Using a passphrase on your ssh key has nothing to do with whether the ssh service is configured to allow or deny passwords.
It’s been easy since the 2000s. This makes it easier to be safer than the built in SSH agent + Keychain but pure usability was a solved problem around by the turn of the century.
> It's a total pain in the ass to try to have password encrypted gpg or ssh keys in mac
I'm anti-Mac but for the year recently that I had to use one at work, no choice...I had no issues, none, using gpg or using a passphrase on my ssh keys.
I've used password-encrypted keys on a Mac plenty of times. It was easy to add them to the SSH agent to not require a password after initial authorization, if that's what I wanted. What is the issue I'm not seeing?
If the Secure Enclave on your Mac is backdoored, the fact that the key from your Yubikey (or whatever HSM) is un-extractable will be a very cold comfort.
If I understand correctly, this means you can't back up the private key, correct? It's in the Secure Enclave, so if you lose your laptop, you also lose the key? Since it looks like export only really exports the public key not the private one?
Probably not the worst thing, you most likely have another way to get into the remote machine, or an admin who can reset you, but still feels like a hole.
Or am I missing something?
ps. It amuses me that my Mac won't let me type Secure Enclave without automatically capitalizing it.
Edit: I understand good security is having multiple keys, I was simply asking if this one can be backed up. OP answered below and is updating their webpage accordingly.
Check out `man sc_auth`. There's also an exportable variant where the private key is encrypted using the secure enclave as opposed to generated on the secure enclave:
You can then re-import it on another device
I'll add this to the guide
Is there a way to import an existing (compatible) key and still mark it as non-exportable?
That seems more useful for the SSH key scenario: Generate a key in memory and back it up to offline storage once, and otherwise only use it in a way totally non-exportable by any malware.
This sentence
> The exportable private key is encrypted with Elliptic Curve Encryption Standard Variable IVX963 algorithm which is backed by a Secure Enclave key.
makes it sound like exportable keys might inherently not be Secure Enclave resident in Apple's implementation, which would be unfortunate, as anything else can still be accessed by malware with kernel-level privileges.
(GPG, and I believe also PIV, allow importing externally-generated keys without necessarily marking them exportable; they'll just, correctly, lack any attestation statement about having been generated in secure hardware.)
7 replies →
How is this method any different from encrypting the private key without any secure enclave?
Isn't it just using a password derived key?
24 replies →
Can you explain which keys in the secure enclave make this work because it has at least two keysets: a public-private keypair locked to the root key Apple instantiated in hardware as fused links in the chip and so in theory this could include private keys common to all the devices in this chipset generation, and the locally generated unique keys which are tied to this specific device.
Using the first pair or products of the first pair, means in principle your private key is protected by the goodwill of Apple only: if you allow it to exist at rest in a form only this shroud protects, then Apple can read the private key unless the symmetric algorithm used to "unlock this private key with your password" is a good one, and you chose a password wisely. I haven't used the function so I can't comment how they constrain what you put in as a personal lock on these blobs.
I am not a cryptographer.
“ This is might be considered secure but is convenient for key backup.”
Might want to clean up that sentence.
You're not really supposed to 'export' keys. Any time you move a key you risk exposing it. The idea of PKI is that only public keys move, the private key stays in one place, ideally never seen.
I've been in the security space for 25 years, and understand the theory of PKI. But I've also been in the ops space for 30 years, and understand that if you don't balance security theory with operational practice, critical business functions can fail.
Ideally yes, the private key is never seen. In reality, it needs to be backed up in a secure place so it can be restored in the event of a failure.
37 replies →
It's much safer to export a key one time and import it into a new machine, or store it in a secure backup, than to keep it just hanging out on disk for eternity, and potentially get scooped up by whatever malware happens to run on your machine.
2 replies →
Correct. Set up multiple keys as backups. Thats also a positive, as nothing can leak the key.
Strictly speaking people should be using multiple keys so if a device is lost/stolen, you're not left high and dry. Ideally one per device, especially if they don't support some kind of secure enclave.
I keep one in a yubikey protected by a PIN that sits in a safety deposit box, too. This way if I have my laptop, phone, and day-to-day yubikey is a house that suddenly burns down, I'm still ok.
Inability to export the private key is no different from using an YubiKey? You can't "backup" the private key they generate either.
Yeah, that is why you should not [always (depends on your use case)] generate it on a YubiKey.
You need to have:
- an offline master private key backup (air-gapped)
- primary YubiKey (daily use)
- backup YubiKey (locked away)
- revocation certificate (separate storage) (it is your kill-switch)
Having a second YubiKey enrolled is the standard practice.
What people do wrong is:
- They generate directly on YubiKey
- They only use one device
- They do not create a revocation certificate
- They have no offline backups
You generate your GPG keys on a secured system, load the subkeys (not the master because it is not used for daily cryptography) into the YubiKeys, and then remove the secret keys from this system where you generated the keys.
14 replies →
Which makes yubikey impossible to use with geographically distributed backups. You need the backup available at all times for when you want to register with any new service.
This is why you should use a device which allows exporting the seed, like e.g. multi purpose hardware crypto wallets.
13 replies →
Yes, that's the point, indeed. One key per device, impossible to extract, so you need to break into the device to use the key.
If you want to maintain backup access, you can use an SSH CA to sign your public SSH keys, then keep the private keys on your device. If you keep the CA keys safe (i.e. physically safe on a flash drive), this means you can even add new keys after you lose all your devices.
This way, you only need to trust your one CA on your servers (so you don't need to copy 20 public keys around for every server).
Plus, if you're setting up a (separate) SSH CA, you can also sign servers' host keys, so you don't need to rely on TOFU to prevent MITM attacks, if that's something you care about.
You use multiple keys, if you need a key usable across different systems then buy a yubikey.
This is the fundamental paradox of hardware secured keys. Basic ones generate the private key inside and never let it be exported. This allows you to be very sure it won't ever leak but also doesn't let you back it up. Higher end Hardware Security Modules allow the private key to be exported but only when encrypted with the valid public key of a destination HSM.
> If I understand correctly, this means you can't back up the private key, correct? It's in the Secure Enclave, so if you lose your laptop, you also lose the key?
In a business environment, that's what you want. The key is then burned, and you ask your coworkers (who still have access) to remove the old key and store your new one on the servers.
Right, you can back up the key.
There’s three general approaches to SSH: having per-device client keys, having per-server keys and having the same key everywhere.
A Secure Enclave, Yubikey or other hardware keys work well with the first approach. Ideally, you won’t loose all keys at once.
posting late in the discussion, but you shouldn't back up our private keys. The ideal setup is with ssh-ca's anyways.
You shouldn’t be backing these keys up anyway imo
I had being using krypton, with the private key being on my iPhone, and am now using secretive. Never had much of an issue with not having access to my private key. We made rolling out public keys to the servers very easy by using the gitlab key file. So when I get a new Macbook I'd just need to create a new key and upload it to gitlab. We have multiple devops that can run the playbook to roll it out to the servers. And if they have a new Macbook I roll it out for them. And we don't have that many Macbook upgrades anyway.
[dead]
Ok I wished for this kind of feature for years. I started using a yubikey with an ssh key via gpg ssh-agent in 2018 or 2019. When resident ssh keys came around I switched over to FIDO2 based keys on my yubikey. The main issue with both was the fact that the default ssh setup wasn’t working anymore. One needs extra configs and more commands to get to the public key etc. Yubikey’s are great but block an USB port. And then there is the age old question for me: One SSH key per User for all services? One key per machine for all services? Or one key per service? This year I started to play around with the 1Password ssh-agent feature (bit warden has it as well as far as I know) If you're ok with allowing all your keys being listed in the agent this works pretty easy out of the box. I never liked the fact that the default recommended way to use ssh is to use an agent that just has multiple keys which can be tested one after another and in most cases stay unlocked there after first use for the rest of the session. I configured around to make sure that I explicitly use one key for one specific service. But that is sadly extra configuration etc etc.
I believe that in 1Passwd you can define / preselect a key per host now. So you can pinpoint key -> host. Some hosts have firewall rules that will block after X attempts were X might be low.
However the agent still has access to all your keys, obviously.
Thanks for this info. First I'd heard of it. Here's a link for others. https://developer.1password.com/docs/ssh/bookmarks/
Ah cool. I worked around by storing the public keys in my dot repo and use the identity file ssh config option for said host. Great if I don’t have to do this anymore.
Next level config madness: Use different ssh keys per GitHub org ;).
Secretive is a bit friendlier to set up but I'll probably switch to this anyway so I have one less app on my computer.
Plugging my blog post for how to achieve this on Windows 11:
https://cedwards.xyz/tpm-backed-ssh-keys-on-windows-11/
Is storing ssh-key in tpm possible on Linux?
https://github.com/Foxboron/ssh-tpm-agent works well for me
Yes, it's about three to five commands and some configuration to set it up: https://www.ledger.com/blog/ssh-with-tpm
Wonder if it's possible to use keys created by Secretive in native authentication?
side note: It's interesting that the `sc_auth` CLI tool to create the SSH key, is just a bash script! It seems truly ancient, and has comments referencing mac OS Tiger (20+ years old) and non-existent files from old macOS. It calls out to '/System/Library/Frameworks/CryptoTokenKit.framework/ctkcard' (not on PATH) to actually create the ssh key.
This exists: https://github.com/facebookincubator/sks.
It's a golang library that abstracts usage of ssh keys backed by hardware on all sorts of devices - mostly designed for laptops, but supports Linux, Windows and MacOs
A golang library is cool, but it doesn't give you a working ssh-agent.
I started working on one few years ago: https://github.com/Foxboron/ssh-tpm-agent
I've been using this for a ~year now and it works very well. Thanks!
If you're willing to go a bit further you can also do GPG signing with ECDSA, though it requires a patched GPG due to bugs and a patched SSH agent that allows raw signing. We have a packaged version with a macOS UI [0], but the same backend [1] works on Linux using the tpm via PKCS#11.
We have a blog post on this, but I guess it was never made public, but the only difference between GPG and SSH is the way in which keys and signatures are wrapped and listed through the various layers -- it's all just fundamentally ECDSA with a named curve.
[0] https://github.com/KeetaNetwork/agent
[1] https://github.com/KeetaNetwork/agent/tree/main/Agent/gnupg/...
Whoa, that is pretty cool.
I've been using Secretive for years, and prefer it to all the physical key/card based systems I've tried to get going over the years. I know exactly when my SSH key is used for any operation, because I need to hit a button or do a fingerprint scan. I can keep ssh-agent tunnels to remote boxes so that I can sign git commits remotely without having to worry about a rogue system getting complete access to key ops without me knowing what's going on.
However the Tahoe version of secretive is buggy and frequently locks up on initial key op requests. I don't have the bandwidth to debug it and file a bug report, and honesty I'm not sure I want to relearn all that knowledge of SSH to figure it out.
I think the smart card SSH UX is worse than secretive's, IIRC my past pain, but if it is reliable, worth a shot.
> I can keep ssh-agent tunnels to remote boxes so that I can sign git commits remotely without having to worry about a rogue system getting complete access to key ops without me knowing what's going on.
I also really like secretive, but at least this part is not exclusive to it; OpenSSH's `ssh-agent` and `ssh-add` have long supported confirmation of each private key use with `ssh-askpass` (although it unfortunately can't distinguish between remote and local key uses).
Is there a way to make the lifetime of the key last more than a year?
The key itself appears to have no validity period, the validity period is only for the certificate made for the key. Maybe you could create a CSR for the key/identity and then sign it with your own CA (or self-sign with openssl) for whatever validity period you like. Then `sc_auth import-ctk-certificate`.
This seems really cool. I use Secretive and would like to switch to this native solution. The one thing holding me back is that I like that Secretive allows you to create keys that don't require TouchID, yet still notifies you when they are used.
I use an external keyboard, so reaching for the fingerprint reader isn't as easy as it would be if I just used the internal keyboard. Fine, ControlMaster is a good compromise. Except when git signing (every commit) is a requirement, you have to touch the reader every, single, time. That's fine when making routine commits, not so when rebasing. Ideally, I could tell the SecureEnclave to notify me, but don't require biometrics for the next 30 seconds or so, but since that's not a thing, that I'm aware of, I'd at least like to know when my git signing key is being used.
This isn't such a great idea for personal SSH or GPG keys that should be locked away in physical hardware thing that need to be moved to other devices/machines. What security processors are great for is corporate machine, system/service, and user key management IdM/MDM processes that need secret storage.
Furthermore, with portable devices like Yubikey it's possible to create a master Certify-only GPG key where the sub Signature/Encryption/Authentication-subkeys live on the Yubikey. The encrypted C private key part with the S/E/A stubs still needs to be backed-up to some durable, versioned storage that isn't tied to one device.
Finally, use GPG for SSH. And definely avoid file-based SSH local private key management for wherever possible for anything substantial because it doesn't scale well.
> This isn't such a great idea for personal SSH or GPG keys that should be locked away in physical hardware thing that need to be moved to other devices/machines
I would change this: it’s great for personal usage BUT you should always use n>1 keys to avoid being locked out. For example, using the Secure Enclave for your daily use is fine but you’d want to have, say, a FIDO2 hardware key setup so if your laptop fails or is reset you can get into anything where you use that key.
How can I get such a key into my iPhone too, so that I can sign emails and file and such with the same private key when I'm on my phone, and my public key is valid for all such operations ? Will iCloud take care of that ? And then I want it all usable from my (multiple) email clients...
These aren't synced over iCloud
What you're thinking of are Passkeys. Which are synced. Somebody would have to write an SecurityKeyProvider that talks to the Passkey API instead.
Actually I don't think it's completely impossible. The only thing is that passkeys are origin-bound. They belong to a specific AppBundle ID or domain name. If say Secretive would add passkey support then that specific public/private keypair can't be used by another app. Though it does sync across instances of the app across devices.
Clearly I'm hazy on this stuff. But if I can export the private key from my Mac, is there any use for it on my iPhone, and any way to get it in there ?
I guess it would depend on having an SSH app with the right feature ? (import private key, transfered in encrypted form)
This is for SSH, not GPG.
This is a good moment to remind everyone of this excellent guide: https://github.com/drduh/YubiKey-Guide
it describes how to use your YubiKeys (please always use at least two, so that you have a backup) for GnuPG keys and SSH.
I've been using this setup since 2018 and it is brilliant. I know GnuPG is not in fashion these days, but thanks to this setup I have SSH logins using YubiKeys, encrypted backups using GnuPG, and 2-factor authentication for a number of sites that support Webauthn. All with backup keys, which is IMPORTANT: do not get locked into using a single device, because sooner or later you will lose that device or it will suddenly die.
Does the hardware only support the NIST curves? Or is that just the example that happens to be given?
Only supports NIST curves and ECDSA yes.
I've heard people make the point before that EdDSA is not great for secure enclaves due to being suspictable to Fault Attacks which could lead to (partial) key extraction
I don't trust the NIST curves: they were generated in a dubious way which has been written about extensively elsewhere (the coefficients for P-256 were generated by hashing the unexplained seed c49d360886e704936a6678e1139d26b7819f7e90). I always avoid them unless I have to use them. It makes me sad when hardware forces me to use them.
> I've heard people make the point before that EdDSA is not great for secure enclaves due to being suspictable to Fault Attacks which could lead to (partial) key extraction
Huh, got a link? My understanding is that eddsa is better with respect to side channels in every way, that was part of the intent of it's design. I've worked with crypto hardware which supports it.
2 replies →
Does anybody know why 'p-384-ne' (instead of 'p-256-ne') cannot be used?
Key can be generated, but 'ssh-keygen -w /usr/lib/ssh-keychain.dylib -K -N ""' cannot find the key to export.
I think this is an openssh limitation.
openssh only supports sk-ecdsa-sha2-nistp256 and sk-ed25519 security keys iirc
Time to up my game and finish adding new features to KeyMux, which supports enclave keys for SSH, SSL, and PGP, including in mixed-use scenarios, such as secure enclave-backed SSL peer authentication to a Vault server for SSH authentication with a non-exportable Vault private key: https://keymux.com/ (https://apps.apple.com/us/app/keymux/id6448807557)
Oh, this is neat! I wonder if apple just added support for the secure enclave as a provider or if this might help fix the bad experience of yubikeys on the mac. Last time I tried it, the distributed ssh and ssh-agent didn't play well with security keys
Does anybody know if there is something similar for gpg keys? E.g. for commit signing?
That is, natively with the Secure Enclave, not exportable.
Git commits can be signed with ssh keys.
Unfortunately I've found that not every source management tool understands SSH signatures and using them may have your commits end up being shown as signed by an untrusted key.
On Linux, GPG supports TPM2, but I'm not sure if that also works on macOS.
Some Fido2 keys like the YubiKey and Nitrokeys support PGP keys as well. Works pretty nice as well and has the added bonus of your key not being tied to a pice of hardware that is as likely to break like a laptop (or be upgraded on a semi-regular basis)
You can (mis)use ssh keys for git signing, but GPG on gpg-card and S/MIME on PIV card are the two standards and their respective hardware implementations (for signing keys in general.)
See my comment above regarding Keeta Agent, which supports GPG and SSH with the same key.
Its worth noting that this is the likely NSA backdoored curve under the hood and probably should not be used.
This is just so perfect. No longer a 3rd party glue and separate ssh agent is needed.
Awesome.
Won't be ditching Yubikeys just yet but I can see a number of use-cases for this already.
Why would you want the private key file if you store it within the secure enclave?
Probably for the same reason that OpenSSH's `sk` implementation also still needs a private key file (even for the "resident key" option): You need to be able to point OpenSSH's various tools to something in an identity context, and that something traditionally is a private key file.
The article even mentions that it doesn't contain any sensitive data:
> Note that the "private" key here is just a reference to the FIDO credential. It does not contain any secret key material.
It's a slightly different story for non-resident `sk`-backed keys; these actually require the private key file since the hardware authenticator itself is (or at least can be) stateless. (It's still not a security risk if it ever leaks, but it's an availability risk if it's ever lost.)
Not sure if macOS's backing implementation is stateful or stateless (or some unfortunate hybrid of both; i.e., it might just store a stateful wrapped key in some system-level keychain in a way that intransparently breaks if the OS is ever reinstalled, but also doesn't allow querying an intact system for any existing credentials).
Thanks I missed this in the description.
I’m a bit confused as to why you can export the keys. Can someone explain this?
TFA:
> Note that the "private" key here is just a reference to the FIDO credential. It does not contain any secret key material.
Ah, ok, I missed that bit. Thank you!
Fundamental services like DNS, which was designed as distributed going down was the cause last 2 outages and really need to think of alternatives methods to ensure resilience. Shift left, design better.
Bot comment? Or wrong tab? Moderators?
This may be the thing to get me to upgrade to MacOS 26.
It’s not new to Tahoe. I use it on Sequoia.
The command is available on Sequoia too!
It feels pretty good.
nvm
This Gist is about not needing to use Secretive any more.
> Secretive has been around for a while, I don't see why it's coming up now through this gist.
Because this is different !
Secretive required installation, which is both friction and security-sensitive tool written by a third party.
This is native, written by Apple, available out-of-the-box in Tahoe.
It's a total pain in the ass to try to have password encrypted gpg or ssh keys in mac. Nothing better that another way to make it even more painful and complicated, so that people will just store plain text keys to not be annoyed.
> It's a total pain in the ass to try to have password encrypted gpg or ssh keys in mac.
Who uses password encrypted keys anyway ? No exfiltration protection, and a sitting duck for unlimited automated password guessing attempts.
Pre-Tahoe people used Yubikeys or Secretive. But now this native tool is a better option than Secretive, even if Yubikeys still have their uses for the power-users.
With an ssh agent and time-bounded key expiration one can have very strong password on the key that is convenient to use.
Also password managers like 1password or Bitwarden support ssh-agent protocol so one can have a master password that protects both stored passwords and keys.
2 replies →
> Who uses password encrypted keys anyway ?
Edit: I'm not suggesting an ssh key with a passphrase (or password) is better than what the article suggests; I'm only saying that adding a passphrase (or password) to an ssh key at least buys time to address the situation while the attacker is trying to break the encryption on the stolen key.
I am anti-Mac in every way, but I do use passphrase protected ssh keys so if someone were to get a copy of my ssh key, they would have to be able to break the encryption to use the key. I see a lot of devs using blank passphrases on their ssh keys, smh.
> sitting duck for unlimited automated password guessing attempts.
Using a passphrase on your ssh key has nothing to do with whether the ssh service is configured to allow or deny passwords.
5 replies →
This looks like the complete opposite, though? It’s easy and provides a convenient way to integrate SSH and TouchID.
It’s been easy since the 2000s. This makes it easier to be safer than the built in SSH agent + Keychain but pure usability was a solved problem around by the turn of the century.
> It's a total pain in the ass to try to have password encrypted gpg or ssh keys in mac
I'm anti-Mac but for the year recently that I had to use one at work, no choice...I had no issues, none, using gpg or using a passphrase on my ssh keys.
I've used password-encrypted keys on a Mac plenty of times. It was easy to add them to the SSH agent to not require a password after initial authorization, if that's what I wanted. What is the issue I'm not seeing?
I would not trust it personally, specially since the Chip Security Act is looming
https://www.centerforcybersecuritypolicy.org/insights-and-re...
If the Secure Enclave on your Mac is backdoored, the fact that the key from your Yubikey (or whatever HSM) is un-extractable will be a very cold comfort.
-2 after France admitted Apple and Google devices are backdoored
classic hackernewers