| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
First off, this application is likely not secure. It hasn't been audit, fuzz tested, or even really tested at all. That means there's very likely a critical bug that breaks its model.
This page aims to describe the theoretical security of the app, with that in mind. It focuses on cases where this authenticator deviates from what you might expect from the CTAP2 standard.
The core principle of a FIDO2 device is to be one of two factors. The authenticator represents "something you have". The PIN represents "something you know".
Gaining complete access to the authenticator should not be useful for an attacker unless they know your PIN.
Traditional implementations of FIDO2 devices do this by storing the PIN on the device "securely", and then relying on the correctness of their software and the tamper-proofness of their hardware to protect private keying material.
This app is different. In this app, once you set a PIN, the "wrapping key" - without which the authenticator is useless - is encrypted using a key derived from the PIN. This means no credentials can be created or used unless you provide your PIN...
On boot, the device generates an AES256 key, the "wrapping key".
Each individual credential issued by the app is a SecP256r1 keypoint, generated randomly on-device for that credential. The cred private key is then AES256-CBC encrypted along with the RP ID, using a random IV, and the result is used as the "credential ID".
When using resident keys, the cred private key is only stored encrypted (after being initially generated). When not using resident keys, the cred private key isn't stored on the authenticator at all.
This means relying parties are holding their own encrypted private keys. The keypair itself provides approximately 128 bits of brute-force resistance. The wrapping key provides a strong 256 bits.
The wrapping key is - when a PIN is set - encrypted using a "PIN key" produced by running five (by default) rounds of PBKDF2 over the first sixteen bytes of a SHA-256 of the user's PIN, with a 28-byte random salt. This means that "unwrapping" the wrapping key, were an attacker to gain access to it, would require a targeted attack whose brute-force difficulty is at most 128 bits, and is likely set by the entropy of the user's PIN.
Use a strong PIN if you care about security in the event your device is entirely compromised. Despite the name, there is no requirement that PINs be numeric. You can use any sequence of characters up to 64 bytes long.
Your PIN is used for challenge-response to the authenticator at least once per power-up, and it's done encrypted over an ECDH channel. The authenticator returns a 32-byte "pinToken", also encrypted. From then on proof of possession of the PIN is via challenge-response using 16 bytes of the hash of whatever content with pinToken as the key.
In other words, it's pretty secure. The PIN token is rerandomized each time a guess is unsuccessful and each authenticator reset. You can't intercept someone's PIN except when it's being initially set, and even then it's sent encrypted with ECDH. The least secure part of it is when the initial PIN is being set - so do that first!
The wrapping key is stored in RAM from when you enter your PIN until you reset the card, so if you want to be very secure, power the card down each time you finish using it.
The hmac-secret extension keys are made by performing an HMAC-SHA256 of a particular credential's ECDSA private key, using a random 32-byte key generated when the app is first installed. This makes the brute-force resistance of these keys dependent on the entropy in a raw ECDSA private key, which is somewhat less than 256 bits and likely considerably stronger than the ECDSA keypair itself.
The attacker is you. Do better next time.
Yeah, that's how NFC works when your attacker has a nice antenna.
The important parts of the traffic are encrypted and authenticated with ECDH. The attacker cannot reasonably "see" your PIN. They can see incidental data like credential IDs being newly created, but the security impact is minimal.
If they can forge traffic to the authenticator, they could hard-reset it, wiping your keys.
This threat scenario is explored in depth elsewhere, but in brief:
The attacker has fully compromised your security and can use the authenticator to pretend to be you in any way it is able.
Resident keys stored on the device will let the attacker see your user IDs on different web sites, etc. They can use those to log in to those sites.
Non-resident keys are slightly better: the attacker has to guess which service you'd registered with, and your username.
If the smartcard itself is physically secure against having its flash memory read or computation corrupted, this is the same as the "malware" case above. If not, then we are in an interesting situation.
The attacker needs to decrypt the on-device wrapping key. Without doing that, they can read incidentals like:
What they can't do without decrypting the wrapping key is get at your actual credentials for sites - the private keys, the RP IDs, etc. They might - if your device doesn't support transient memory for EC private keys AND was inopportunely powered off the last time you used it - be able to use the most recently used keypair you did.
As described above, the wrapping key is itself encrypted using PBKDF2 with a very low iteration count, performed on the first sixteen bytes of your PIN's SHA256 hash. This means the attacker is unlikely to already HAVE a rainbow table, but they can start brute-forcing your PIN.
If you used a strong PIN, you're likely okay for quite a while.
Anyone can use your authenticator as you. Despite what the CTAP2 standard says about user presence, it's not readily possible to implement a "timeout" on a Javacard 3.0.4 device. Javacard 3.1 introduces an (unreliable) uptime counter....
But the implementation currently always assumes user presence.
This Could Be Better. In the meanwhile, perhaps use an NFC device and physically remove it when not in use.
They could probably install an applet that would make the scenario identical to one where they possessed the card AND the hardware was faulty.
So, lock your smartcard ("set a transit key"), gpp --lock <key> or however you communicate with it.
Deleting a credential doesn't currently wipe it from the flash, just marks it as trashed. But a compromised card is a compromised card...
Keys generated by the card will be weak, so the "wrapping key" will be weak.
This entirely breaks the security model of the card and you can't trust anything it does.
You can see the code, and modify it until you do trust it. The only homespun crypto in the repository is an implementation of HMAC and an implementation of PBKDF2. Those were written because PBKDF2 isn't part of the Javacard API at all, and although HMA-SHA256 is it's not implemented on any of my cards.
Open source is open.
| Back | FazBrowse Home | New Git URL |