[HN Gopher] Native Secure Enclave backed SSH keys on macOS
___________________________________________________________________
Native Secure Enclave backed SSH keys on macOS
Author : arianvanp
Score : 253 points
Date : 2025-11-23 17:55 UTC (5 hours ago)
(HTM) web link (gist.github.com)
(TXT) w3m dump (gist.github.com)
| greatgib wrote:
| 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.
| traceroute66 wrote:
| > 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.
| newsoftheday wrote:
| > 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.
| lloeki wrote:
| > whether the ssh service is configured to allow or deny
| passwords.
|
| Given the consistent use of "password" instead of
| "passphrase", I think they meant an exfil'ed encrypted key
| is vulnerable to no-rate-limit bruteforcing, in contrast
| with hardware-backed keys.
| newsoftheday wrote:
| Right, but my context is that devs often use no
| passsphrase at all. If someone can get a copy, they have
| instant access to whatever it has access to. They don't
| need to even break encryption since the key has none if
| none has been applied. My stance is simply, at least add
| a passphrase to the key (though some call it a password).
| lloeki wrote:
| gotcha, thanks for clarifying!
| Xylakant wrote:
| The parent means that an attacker has unlimited attempts at
| breaking the passphrase on an exfiltrated key. Once the key
| passphrase is broken, they can log in using the key.
| newsoftheday wrote:
| Right, but my context is that devs often use no
| passsphrase at all. If someone can get a copy, they have
| instant access to whatever it has access to.
| fpoling wrote:
| 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.
| manuelabeledo wrote:
| This looks like the complete opposite, though? It's easy and
| provides a convenient way to integrate SSH and TouchID.
| newsoftheday wrote:
| > 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.
| tiltowait wrote:
| 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?
| epistasis wrote:
| 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.
| redrove wrote:
| nvm
| simonw wrote:
| This Gist is about not needing to use Secretive any more.
| traceroute66 wrote:
| > 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.
| traceroute66 wrote:
| Awesome.
|
| Won't be ditching Yubikeys just yet but I can see a number of
| use-cases for this already.
| cedws wrote:
| 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/
| smartbit wrote:
| Is storing ssh-key in tpm possible on Linux?
| agartner wrote:
| https://github.com/Foxboron/ssh-tpm-agent works well for me
| adastra22 wrote:
| I'm a bit confused as to why you can export the keys. Can someone
| explain this?
| lloeki wrote:
| TFA:
|
| > Note that the "private" key here is just a reference to the
| FIDO credential. It does not contain any secret key material.
| adastra22 wrote:
| Ah, ok, I missed that bit. Thank you!
| jedberg wrote:
| 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.
| justincormack wrote:
| Correct. Set up multiple keys as backups. Thats also a
| positive, as nothing can leak the key.
| comprev wrote:
| Inability to export the private key is no different from using
| an YubiKey? You can't "backup" the private key they generate
| either.
| johnisgood wrote:
| 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.
| epistasis wrote:
| I can understand revocation for GPG, but is revocation ever
| used for SSH? I could understand it if SSH certificates are
| used, but honestly I've never encountered an org using
| SSH's cert system.
| johnisgood wrote:
| Well, OpenSSH has a built-in key revocation mechanism
| (KRL which is just SSH revocation), and there are SSH
| certificates (with a CA) and certificate revocation, and
| there is ad-hoc "revocation" by removing keys from the
| "authorized_keys" file.
|
| If you use your GPG key for SSH, the servers that have
| your public key do not automatically know that your GPG
| key was revoked, and SSH authentication will proceed
| unless you remove the public key from the server OR the
| server uses an SSH CA/KRL model.
|
| All in all, SSH supports real revocation, but it must be
| enforced by the server. It is different from GPG where
| revocation follows the key, not the server.
|
| I have not used KRL myself, but I sort of know how it
| works. You can generate a new empty KRL, then add keys to
| revoke, and then to distribute the KRL to servers by
| configuring OpenSSH to use the KRL file, by adding
| "RevokedKeys /etc/ssh/revoked_keys.krl" to
| "/etc/ssh/sshd_config".
|
| The pros of KRL is that they scale better than manual
| removal for multiple servers, and you can revoke entire
| CA ranges instead of individual keys if using SSH
| certificates which is recommended for large setups.
|
| I hope I could clear some things up. Let me know if you
| have any questions though!
| eptcyka wrote:
| You are talking about GPG keys. The featured article only
| refers to SSH keys. Know the difference.
| johnisgood wrote:
| I know the difference, thank you for your concern.
| traceroute66 wrote:
| > Yeah, that is why you should not generate it on a YubiKey
|
| No. You should _ALWAYS_ generate on the Yubikey. That 's
| the whole point.
|
| Your backup is one (or more) other keys.
| johnisgood wrote:
| Depends on your use case, and you will still have to
| generate your master key offline even if you want the
| subkeys generated directly on each YubiKey, which then
| you sign with the master key.
|
| It is only slightly less secure if you pre-generate
| subkeys on an offline machine if you want identical
| subkeys on multiple devices (and if you want exact
| backups). Sometimes this is exactly what people want.
|
| Ultimately it really depends on your use case.
|
| BTW, please check the parent comments to which I
| responded.
|
| PS. I think it would be useful for others if you
| elaborated on your statements (for educational purposes).
| doublepg23 wrote:
| Do you have a good guide/video/write up on this?
|
| I've been putting off remaking my GPG and SSH keys using a
| Yubikey.
| nothrabannosir wrote:
| 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.
| epistasis wrote:
| Are you talking about SSH or a different setting?
|
| With SSH, you can always share the primary and backup pub
| keys, even if you don't have the backup key handy.
| nothrabannosir wrote:
| No I got distracted by the word yubikey. Arguably not the
| same subject. :)
| epistasis wrote:
| Nonetheless I'm glad to hear about it. I don't yet use
| YubiKeys for FIDO, because I was concerned a bit about
| this enrollment process, and hadn't bothered to figure
| out what others do.
| traceroute66 wrote:
| > Which makes yubikey impossible to use with geographically
| distributed backups.
|
| Huh ?
|
| You do know you can wrap a symmetric key with multiple
| asymmetric keys, right ?
| arianvanp wrote:
| 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:
|
| I'll add this to the guide
| sroussey wrote:
| " This is might be considered secure but is convenient for
| key backup."
|
| Might want to clean up that sentence.
| rjdj377dhabsn wrote:
| How is this method any different from encrypting the private
| key without any secure enclave?
|
| Isn't it just using a password derived key?
| arianvanp wrote:
| The key is stored encrypted with a unique symmetric key
| that only your secure enclave knows until the point that
| you export it. It then re-encrypts it with the password.
|
| Until you export it it's just as strong as an enclave-
| generated one.
|
| Obviously don't keep the exported password encrypted key
| around and don't use a weak password for export.
| gruez wrote:
| >The key is stored encrypted with a unique symmetric key
| that only your secure enclave knows until the point that
| you export it. It then re-encrypts it with the password.
|
| But what's the security benefit of this compared to
| having a keyfile? So far as I can tell from the commands
| you provided, there's no real difference, aside from a
| hacker having to modify their stealer script slightly.
| arianvanp wrote:
| Why is it more secure: a key file on disk is decrypted
| into memory every time you enter your passphrase. It
| means the key is around in plain text in the memory of
| ssh or ssh-agent. Which means it's extractable by an
| attacker. An exportable key does all the signing inside
| the secure enclave and never exposes the decrypted key to
| OS memory.
|
| The exported key you can keep in a safe for disaster
| recovery. You shouldn't keep it on your computer of
| course.
| traceroute66 wrote:
| > The exported key you can keep in a safe for disaster
| recovery.
|
| No. Your "disaster recovery" should be either a second
| device with a Secure Enclave, or a Yubikey.
|
| Making it exportable from the Secure Enclave defeats the
| whole purpose.
| gruez wrote:
| >It means the key is around in plain text in the memory
| of ssh or ssh-agent. Which means it's extractable by an
| attacker. An exportable key does all the signing inside
| the secure enclave and never exposes the decrypted key to
| OS memory.
|
| But malware can just tell the secure enclave to export
| the key? Yes, they'll have to write new code to do that,
| but it's not particularly hard (it's 1 line code from
| your example above), and it's security through obscurity.
| monocularvision wrote:
| The malware would have to prompt for biometric
| authentication before exporting.
| Nextgrid wrote:
| So it just has to wait until you're about to do a
| legitimate operation requiring authentication, intercept
| that to export the key, and cancel the real one with a
| bogus error (and you'll just try again without any second
| thoughts).
|
| MacOS has also no concept of secure desktop/etc where the
| OS can use some privileged UI to explicitly tell you what
| you are signing and prompt for PIN/biometrics. It's in
| fact a well-known problem where legitimate dialogs for
| system/Apple ID password have no distinguishing features
| from fake ones.
| arianvanp wrote:
| The export operation is guarded by TouchID. So the
| malware needs to trick you into performing the TouchID
| gesture.
|
| But yeh the malware only needs to trick you to hit
| TouchID once. Instead of on each sign operation. So if
| that's in your threat model don't make the key
| exportable.
| gruez wrote:
| > So the malware needs to trick you into performing the
| TouchID gesture.
|
| That's not meaningfully more difficult than tricking you
| into revealing your key file password.
|
| >Instead of on each sign operation.
|
| But from your video each sign operation also requires a
| touchid prompt?
| epistasis wrote:
| As a user I prefer a single touch to typing a passphrase
| every time. A passphrase also has other attack vectors
| like keylogging, etc., which would allow replays.
|
| But even if security was exactly the same, I'd prefer the
| touch to the typing.
| cedws wrote:
| 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.
| jedberg wrote:
| 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.
| pi-rat wrote:
| You can use more than one key you know.
|
| Keep the private key you actively use in the secure
| enclave. The system you actively use is most at risk.
|
| Keep a secondary offline private key as backup. You can
| generate and store it in a secure location, and never move
| it around. Airgapped even if you want. You could even use a
| yubikey or other hardware for the secondary key giving you
| two hard to export keys.
|
| Distribute pub keys for both of them.
|
| Best of both worlds?
| morshu9001 wrote:
| Yeah but if you get a new device, you have to go add its
| pubkey to every server you ever use. I wish there were an
| easier way, otherwise it's understandable that people
| copy privkeys.
| yjftsjthsd-h wrote:
| There is an easier way: Create a SSH CA, add _that_ to
| your authorized_keys everywhere, use it to sign the
| individual public keys.
| arianvanp wrote:
| Yep that's what I do! I have two ssh-ca's stored on two
| Yubikeys. And both are trusted by my servers.
|
| If I lose one I can still sign new certs with the other.
|
| https://github.com/arianvp/nixos-
| stuff/blob/master/modules/s...
| vlovich123 wrote:
| It's important to remember that over time systems develop
| complexities that can be hard to recover from scratch
| because by definition air gapped data aren't ones you are
| regularly exercising. Here's an example of this in action
| from Google's history
|
| https://google.github.io/building-secure-and-reliable-
| system...
| eptcyka wrote:
| In what scenario would you prefer to backup an SSH key in
| favor of generating new SSH keys?
| jedberg wrote:
| When I have my pub key in the authorized_keys files of
| many machines, especially machines where I don't control
| the authorized_keys file.
| philsnow wrote:
| > if you don't balance security theory with operational
| practice, critical business functions can fail
|
| i.e. people will circumvent the secure-but-onerous path. (I
| don't think they can be faulted for trying to get their
| work done either, I'm agreeing with you)
| adastra22 wrote:
| I think you are mixing up concerns. You need a backup key.
| That doesn't mean you need to backup your key.
|
| Anything (everything?) using SSH authentication supports
| multiple authentication keys. Have a yubikey in a locked
| deposit box or something.
| jedberg wrote:
| Today I make a private/public keypair, and the private
| key is on my laptop in my encrypted home folder. It also
| gets backed up to my encrypted offsite backup. That way
| if my laptop breaks or is stolen, I can restore from
| backup and be up and running as before.
|
| I was simply asking if that is still possible with this
| method, nothing more.
|
| And not every service that uses ssh auth allows multiple
| keys.
| asteroidburger wrote:
| 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.
| hylaride wrote:
| 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.
| aaomidi wrote:
| You shouldn't be backing these keys up anyway imo
| midtake wrote:
| You use multiple keys, if you need a key usable across
| different systems then buy a yubikey.
| jeroenhd wrote:
| 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.
| procaryote wrote:
| 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
| wahern wrote:
| 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)
| cube2222 wrote:
| 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.
| fpoling wrote:
| Git commits can be signed with ssh keys.
| jabberwhookie wrote:
| 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.)
| moooo99 wrote:
| 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)
| berzan wrote:
| This is just so perfect. No longer a 3rd party glue and separate
| ssh agent is needed.
| redleader55 wrote:
| 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
| Foxboron wrote:
| 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
| agartner wrote:
| I've been using this for a ~year now and it works very well.
| Thanks!
| euroderf wrote:
| 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...
| arianvanp wrote:
| 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.
| watermelon0 wrote:
| 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.
| arianvanp wrote:
| I think this is an openssh limitation.
|
| openssh only supports sk-ecdsa-sha2-nistp256 and sk-ed25519
| security keys iirc
| jcalvinowens wrote:
| Does the hardware only support the NIST curves? Or is that just
| the example that happens to be given?
| arianvanp wrote:
| 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
| jcalvinowens wrote:
| 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.
| WhereIsTheTruth wrote:
| I would not trust it personally, specially since the Chip
| Security Act is looming
|
| https://www.centerforcybersecuritypolicy.org/insights-and-re...
| adastra22 wrote:
| Is there a way to make the lifetime of the key last more than a
| year?
___________________________________________________________________
(page generated 2025-11-23 23:00 UTC)