How passkeys will impact app security and set us free
Find out more about the latest authentication trend and discover technical details behind passkeys both from the perspective of a user and a developer
Passwords have been the liability for secure authentication for years. We have still been trying to salvage this by creating a wobbly build-up on top of the standard authentication form – password requirements, SMS codes, OTPs… adding more locks on something that looks like a barn door. Users who are still trying are left confused with an enormous keychain in one hand, a bunch of second factors in the other, and the average Joe is not even aware that he has left the door wide open, since his password is dolphins.
Enter passkeys. As soon as passkeys were introduced, all major tech portals proudly announced: passwords are dead. However, as for now, nothing has changed apart from a few applications – passwords and MFA are still standard.
In this article I will:
- Tell you more about problems caused by passwords.
- Explain in simple terms how passkeys work (both empirically and technically).
- Discuss security measures implemented in passkeys.
- Explain why you should jump into passkeys depending on whether you are a curious user, a developer, or an admin.
The article will start with simplified terms to ease your transition into the passwordless world, but you can expect more technical details and clarifications in the later sections.
Why passkeys? Pitfalls of password authentication
Let’s take a look at the current set of authentication best practices. Summarized:
- An account should be protected with a password that meets the complexity requirements together with MFA.
- MFA may be a TOTP, a push notification on your phone, an SMS code, or sometimes a hardware key.
- Passwords should be stored in a database as a salted hash (sometimes also peppered).
- An application should implement protection against brute-force (using many passwords from a dictionary against a single account), password spraying (using a single common password against many accounts in the same application), and credential stuffing (using credentials from data breaches).
In reality:
- Most applications, even if they have MFA implemented, do not actively require or encourage the user to set it up. You must know it exists and want to have it. However, it makes the registration process much longer and less pleasant.
- Password complexity requirements are often “outsmarted” by the users by creating a predictable password concatenated with current year and an exclamation mark. The hottest password this season: Winter2023!
- Even though more and more applications implement protection against standard brute-force, they are usually still vulnerable to password spraying and credential stuffing as they only detect multiple failed authentication attempts against a single account and ignore thousands of requests targeting thousands of different accounts. If users do not have MFA and reuse passwords, they are likely to fall victim to a stuffing attack.
- Even if passwords are salted, in case of a breach, simple passwords will be cracked.
- And the final nail in the coffin – in case of a phishing attack, MFA will not be your rescue unless you use a hardware authentication device (U2F). If you use TOTP (basically any authenticator), the attacker will just present you with a form asking for the code, which they will instantly use to log in to your account. This is easy.
Passkeys are the remedy to all the above, remaining at the same time simple to set up and easy to use. We will get back to this in the next sections.
How to use passkeys? Passkey setup from a user’s perspective
We already know the current state of authentication in web applications and are aware of its downsides. Now, we will see passkeys in action. To begin with, let’s put some context behind this phrase – here is a simple definition of passkeys:
Passkeys are a new kind of passwordless authentication that can be used instead of passwords and MFA. They are based on public-key cryptography and are more secure and convenient.
So, what are the steps you should take to start using passkeys? We will use the example of passkeys implementation on webauthn.io, but there are many other websites you can use (like webauthn.me). First, you must register.
1. Insert your username.
2. Scan the QR with your phone. Make sure you have a Bluetooth connection turned on both on your phone and your computer!
3. Confirm your identity (via biometrics or PIN) and save a new passkey on your phone.
Next, you can log in.
1. Again, insert your username.
2. Scan the QR with your phone. Remember about Bluetooth.
3. Confirm your identity and use the passkey from your phone.
That’s it! No need for passwords or configuring MFA. Fast and simple. Try it out either in Chrome, Edge, or Safari (as for today, Firefox supports only hardware tokens), both on your computer and your phone: https://webauthn.io/
Can passkeys be shared among different operating systems?
You might ask yourself – how passkeys work with different ecosystems? What if I had an iPhone but my computer had Windows? Can I share my passkeys among my devices? Do I have to sync everything to the cloud?
No need to worry – the OS does not matter for the convenient usage of passkeys. In most cases, your passkey operation center will be your phone, which allows both creating and managing passkeys and logging in on other devices by scanning the QR code presented by a browser.
- The passkeys are managed by a password manager – they are already available in the built-in iCloud Keychain and Google Password Manager (so you can use them both with iOS and Android). They are also actively implemented by other password managers.
- If you use the iCloud Keychain, your passkeys can be synced across all your Apple devices, the same as passwords – then you will not have to scan the QR code from the browser. Similarly, passkeys managed by Google Password Manager will be synced with your Google account. However, it is not obligatory. You do not have to sync your passkeys to the cloud – you can just log in everywhere with your phone. However, if you lose your phone, you will have to reset all your passkeys – the situation is the same as with normal passwords.
- Regardless of whether you sync your passkeys to the cloud and independently of your devices’ OS, you can always log in using your phone by scanning the QR code. You can see this in the above example – I logged in on a laptop with Windows using a passkey saved on my iPhone.
Technical details of passkeys explained
Passkeys vs WebAuthn
First, let’s clarify the terminology. Passkeys are based on a standard called WebAuthn, which defines an API for creating and accessing credentials based on public key cryptography for user authentication. In other words, passkeys are an implementation of WebAuthn.
WebAuthn vs CTAP
Another protocol which is used in the authentication flow is CTAP2 (Client To Authenticator Protocol). It defines communication between a client (such as a browser) and an authenticator (in this case, your phone) using BLE, USB, or NFC. After you scan the QR code, it will use CTAP2 to check proximity to the client and send required data.
Also, there is one small plot twist – passkeys currently use caBLEv2 (cloud-assisted BLE, also called hybrid), which does not require pairing your phone or installing any additional apps in order to communicate via Bluetooth.
Passkeys vs FIDO2
FIDO2 (Fast Identity Online 2) is a set of open standards for secure and convenient online authentication. It consists of WebAuthn, on which passkeys are based, and CTAP.
How do passkeys work?
Now, we are finally ready to look under the hood and see the technical details behind the passkeys.
The examples will be based on the authentication flow from webauthn.io. If you try to log in, after supplying your username, the server (or, according to the standard, the Relying Party) will send you the following data:
{
"challenge": "A2wSuWw8WJGbuD0ropX4AQF2-q2SnG_Y0YBlJhtUxGE4uzkaWCxNt8pKnOjoJOdzABY5R2Ai19b3ECmZ0vQKcQ",
"timeout": 60000,
"rpId": "webauthn.io",
"allowCredentials": [
{
"id": "XJpfqITANNWwsoOrryLOTbgTQFg",
"type": "public-key",
"transports": []
}
],
"userVerification": "discouraged"
}
The most important parameter in the above request is the challenge, which is a random value different each time you want to sign in. We can also see that the server will wait exactly 1 minute for our response (timeout: 60000 milliseconds). It self-identifies as webauthn.io and suggests using a specific public key if there are multiple credentials saved on my device (since I supplied my username). The server also discourages user verification (so that the authenticator itself is not required to verify whether the user is authorized to use it), but my iCloud Keychain will ignore it and verify my biometrics anyway.
Next, the following values will be sent to my phone via CTAP:
- rpId – the Relying Party identifier, as defined by a user agent (a browser). It should be noted that even though the rpId is usually supplied by a server, a browser will verify it on its own and use only the supplied value if it is correct. Your authenticator (phone) can trust that the authentication request is for the specific Relying Party, not for attacker.com.
- clientDataHash – the cryptographic hash of client data which includes the desired action (webauthn.create – to create a new passkey, or webauthn.get – to access an existing passkey), the challenge, the origin, and some other data.
The authenticator will now process an authentication request and calculate the authenticatorData, which contains the hash of rpId the credential is scoped to, some flags that carry information about whether the user was present and verified, and a signature counter increased with every authentication request that helps detecting cloned authenticators. The signature will be calculated in the following way:
Then the authenticator sends the authenticatorData, the signature, and the credential identifier (a string that makes it possible to identify the public key used to sign the request) back to the user agent (you can check the response structure here). We can see it in the HTTP request sent back to the server after we completed the authentication process on our phone:
{
"username": "natalia",
"response": {
"id": "XJpfqITANNWwsoOrryLOTbgTQFg",
"rawId": "XJpfqITANNWwsoOrryLOTbgTQFg",
"response": {
"authenticatorData": "dKbqkhPJnC90siSSsyDPQCYqlMGpUKA5fyklC2CEHvAdAAAAAA",
"clientDataJSON": "eyJ0eXBlIjoid2ViYXV0aG4uZ2V0IiwiY2hhbGxlbmdlIjoiQTJ3U3VXdzhXSkdidUQwcm9wWDRBUUYyLXEyU25HX1kwWUJsSmh0VXhHRTR1emthV0N4TnQ4cEtuT2pvSk9kekFCWTVSMkFpMTliM0VDbVowdlFLY1EiLCJvcmlnaW4iOiJodHRwczovL3dlYmF1dGhuLmlvIiwiY3Jvc3NPcmlnaW4iOmZhbHNlfQ",
"signature": "MEQCIE8fkw_Fnm9-VkKArwyDYx4b4stEmxi-jQkvEjYCenOOAiBmA-TwIKrNPESJwo1SkA58xI3Nkebs8mf5DlyloReVxg",
"userHandle": "bmF0YWxpYQ"
},
"type": "public-key",
"clientExtensionResults": {},
"authenticatorAttachment": "cross-platform"
}
}
As we can see, the clientDataJSON is consistent with what we described while discussing the clientDataHash calculated by the browser:
{
"type": "webauthn.get",
"challenge": "A2wSuWw8WJGbuD0ropX4AQF2-q2SnG_Y0YBlJhtUxGE4uzkaWCxNt8pKnOjoJOdzABY5R2Ai19b3ECmZ0vQKcQ",
"origin": "https://webauthn.io",
"crossOrigin": false
}
What is more, there is the id and the rawId, which are the identifiers of my public key.
We can also deconstruct the authenticatorData provided by my authenticator. After decoding it with base64 we will get the following values:
The first 32 bytes are the SHA256 of the rpId, which is webauthn.io. The next 1 byte must be converted into binary: 00011101. Then, we will analyze it starting with the least significant bit (from the right):
- Bit 0 (1): The user is present
- Bit 1 (0): Reserved for future use
- Bit 2 (1): The user is verified
- Bits 3-5 (110): Reserved for future use
- Bit 6 (0): The authenticator did not add attested credential data
- Bit 7 (0): The authenticator data does not have any extensions
The last part (4 bytes) of the authenticatorData is the signature counter, which does not seem to be implemented (as it is not an obligatory feature).
After we send all the above data back to the Relying Party, they will verify if the data is correct and the same as expected (including the challenge) and check the signature against the public key stored in their database.
Passkeys in comparison to other authentication solutions
Passkeys vs YubiKey
When someone talks about passkeys, they usually mean copyable passkeys developed by Apple, Google, and Microsoft. These companies have popularized the idea of using passkeys as both authentication factors. The other terms copyable passkeys can be described with include: syncable, backup-enabled, shareable, and multi-device.
The opposite of a copyable passkey is a hardware-bound passkey (or: single-device passkey). YubiKeys can store a limited number of passkeys, but they are not syncable – your passkeys are stored only on your YubiKey, meaning that you should have a backup MFA channel in case you lose your YubiKey.
Considering the above, you can generally think of passkeys as the same thing as the YubiKey with the only difference – the physical proximity is determined by BLE, not USB or NFC.
If you want to find out more about the differences between passkeys and YubiKeys as well as the overall assessment of syncable passkeys versus hardware bound passkeys, check out this Yubico FAQ about passkeys.
Why do we talk specifically about YubiKeys? The reason is, not every hardware-bound authenticator implements FIDO2 (passkeys). Some implement just U2F (FIDO). If you wonder if the authenticator you would like to purchase implements FIDO2, you can check it on FIDO Alliance website.
Passkeys vs OpenID Connect
You might wonder – what about OpenID Connect? What is the SSO of tomorrow? Do not worry, OpenID Connect is safe – passkeys are supposed to take the place of passwords. The use case here is quite different – with OpenID Connect, the authentication is delegated to a third party (the Identity Provider such as Google, Apple, or Facebook), whereas with passkeys you can create an account directly with the Relying Party (the application). These features are quite different privacy-wise, as you do not always want the application to know your real identity and Facebook to know which applications you use. We can also benefit from both worlds by logging into the Relying Party via an Identity Provider that supports passkeys – providing even more seamless experience.
Are passkeys secure?
Passkeys have multiple security features making them a lot more secure than passwords – even passwords together with a second factor of authentication (okay, unless it is an U2F). Let us discuss the most important security features in passkeys.
- Passwords are guessable and often reused. Passkeys never are. The concept of passkeys significantly reduces the threat of any brute-force attacks since they are unique, mathematically complex, and not reused.
- The MFA is already built-in – passkeys are something you have (your phone) and something you are (biometric verification) or something you know (PIN). No need for additional configuration.
- Passkeys are based on public key cryptography. The Relying Party has access only to the public key – which is not interesting to the attacker. Of course, a data breach would still be a terrible thing as it might expose personal data, but it would not lead to account takeovers. To log in, you must have the private key, which is stored in the passkey manager on your device and should never leave it in an unencrypted form.
- Passkeys prevent phishing. First, we have the proximity check – if someone sends you a QR code, they will not be able to steal your account even if you scan it. On the other hand, if you enter an attacker’s website with a similarly looking domain, it will not be able to ask for passkeys generated for a different origin, since passkeys are bound to the domain they were created for.
When will passkeys be widely available?
Passkeys are currently supported by most modern browsers and password managers such as iCloud Keychain (if you have an iPhone) or Google Password Manager (if you use an Android). The only issue that prevents us from adopting passkeys is that there are few applications that would support them as the primary method of authentication. However, the idea is gaining momentum the more we talk about it. If you want to check which websites support passkeys, I recommend you this list.
What do we recommend? The next steps
For a user
I think passkeys will be getting more popular in the next years – and we will find our way into the transition as time goes on. I know waiting can be frustrating (it sure is for me) – but passkeys are still quite new, and Rome wasn’t built in a day. In the meantime, remember about MFA, use a good password manager – and check if your family and friends do as well since less technical people are most likely to reuse weak passwords.
For a developer
If your application is aimed at personal accounts, I think it is a wonderful idea to implement copyable passkeys for low to medium risk applications. This will provide much more security for your users while still being convenient, allowing you to mitigate brute-force attacks and worry less about credential breaches.
For high-risk applications, consider hardware-bound passkeys and U2F, which are still recommended as providing the highest level of security. However, always remember about a secure account recovery policy in case the user loses their YubiKey.
For business-oriented applications, stick to providing support for SAML and OpenID Connect.
For an enterprise
What about enterprise authentication? The standard for secure identity management inside an organization is using a single account with a company-wide Single-Sign On. The Identity Provider (usually AD) utilizes a strong password policy and enforces MFA (SMS or push notifications). However, even with MFA, you can still be vulnerable to phishing since an attacker can create a malicious website that will simply ask the victim to provide their username, password, and OTP (or accept an authentication request). Also, in case an attacker could guess the victim’s password, there is a risk of leveraging the MFA fatigue attack for push notifications.
Copyable passkeys are a viable alternative for NIST AAL2 (Authenticator Assurance Level 2), as they provide the same level of assurance as passwordless Microsoft Authenticator verification while also checking the physical proximity – and is a much better choice than just a password while still being convenient. However, for NIST AAL3 you would need a hardware-bound authenticator like a FIDO2 security key or a Smart Card. You can read more about the comparison of different authentication options here, and find the best option that would work for you and your company considering your use case.
The future is passwordless
Passkeys are a marvelous cure for most of our personal authentication needs while still maintaining a desired level of privacy and convenience. For me, there is no doubt that the future is passwordless. The only question is – how far away is that future?
If you would like to discuss the security of your application authentication schemes or the IAM in your company, we will be happy to help! Use our contact form at the top of this page, or just click here.
Additional resources
- FIDO Alliance Passkeys FAQ
- Apple documentation and presentation from WWDC 2022 that explains how passkeys work and shows an example implementation
- TidBITS: Why Passkeys Will Be Simpler and More Secure Than Passwords