Enhancing Authentication with Passkeys in iOS Using Advanced Techniques

Batikan Sosun
Sahibinden Technology
4 min readMay 14, 2024

A Deep Dive into Technical Implementation

Photo by Markus Spiske on Unsplash

Passkeys revolutionize authentication mechanisms in iOS apps by replacing traditional passwords with iCloud Keychain’s public key credentials. This article provides an in-depth technical exploration of passkey implementation, covering account registration, authentication, AutoFill integration, passkey management, and usage in web views. Accompanied by the code examples, developers will gain comprehensive insights into leveraging passkeys to enhance security and user experience.

The Apple example project can be downloaded here.

In the realm of iOS app development, passkeys emerge as a sophisticated alternative to passwords, leveraging biometric identification and robust cryptographic protocols. This article delves into the technical intricacies of implementing passkey authentication in iOS applications, empowering developers to create secure and user-friendly authentication experiences.

Important note: Registration and assertion requests require an associated domain with the webcredentials service type; otherwise, the request fails. For more information, visit Supporting associated domains.

Passkeys eliminate passwords by using iCloud Keychain public key credentials. For creating and authenticating accounts, they rely on biometrics, such as Touch ID and Face ID in iOS, or specific confirmations in macOS.

Account Registration

The process of onboarding users to services without passwords involves generating unique public-private key pairs for each account. Developers can initiate this process by creating a registration request using the ASAuthorizationPlatformPublicKeyCredentialProvider class. Below is a code snippet illustrating account registration:


// Obtain challenge and user ID from the server
let platformProvider = ASAuthorizationPlatformPublicKeyCredentialProvider(relyingPartyIdentifier: “example.com”)
let platformKeyRequest = platformProvider.createCredentialRegistrationRequest(challenge: challenge, name: “Anne Johnson”, userID: userID)
let authController = ASAuthorizationController(authorizationRequests: [platformKeyRequest])

authController.delegate = self
authController.presentationContextProvider = self
authController.performRequests()

Authentication

Authentication with passkeys involves obtaining a challenge from the server and creating an assertion request. The ASAuthorizationPlatformPublicKeyCredentialProvider class facilitates this process, as demonstrated below:


// Obtain challenge from the server
let platformProvider = ASAuthorizationPlatformPublicKeyCredentialProvider(relyingPartyIdentifier: “example.com”)
let platformKeyRequest = platformProvider.createCredentialAssertionRequest(challenge: challenge)
let authController = ASAuthorizationController(authorizationRequests: [platformKeyRequest])

authController.delegate = self
authController.presentationContextProvider = self
authController.performRequests()

Handling Authorization

The ASAuthorizationControllerDelegate protocol provides methods to handle the outcome of registration and authentication requests. Developers can implement these methods to manage successful authorization or handle errors gracefully.

func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
if let credential = authorization.credential as? ASAuthorizationPlatformPublicKeyCredentialRegistration {
// Take steps to handle the registration.
} else if let credential = authorization.credential as? ASAuthorizationPlatformPublicKeyCredentialAssertion {
// Take steps to verify the challenge.
} else {
// Handle other authentication cases, such as Sign in with Apple.
}
}

func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
let authorizationError = error as? ASAuthorizationError
// Handle the error.
}

AutoFill Integration

Passkey integration seamlessly extends to iOS AutoFill, enhancing the user experience during authentication workflows. By setting the textContentType property of relevant text fields to “username” and invoking performAutoFillAssistedRequests(), developers enable the system to suggest passkeys stored for the app.

Passkey Management

To change or reset a passkey, users can initiate the process through their iOS app, typically in the settings or account management section. Upon selecting the option to change or reset the passkey, the app will prompt the user to confirm their action.

Behind the scenes, the app utilizes the createCredentialRegistrationRequest method provided by the ASAuthorizationPlatformPublicKeyCredentialProvider class to initiate the passkey change/reset process. This method triggers the generation of a new public-private key pair on the user's device.

Once the new key pair is generated, the app sends the new public key to the server, indicating the user’s intention to change/reset their passkey. The server validates the request and associates the new public key with the user’s account, effectively replacing the previous passkey.

It’s crucial for the app to discard the previous public key stored on the server to maintain security and prevent unauthorized access. By replacing the old public key with the newly generated one, the server ensures that future authentication attempts will utilize the updated passkey.

Furthermore, registering a passkey with the same user ID as an existing one will overwrite the existing passkey on all of the user’s devices. This ensures consistency and prevents conflicts between different passkeys associated with the same user account.

In summary, the process of changing or resetting a passkey involves generating a new key pair, updating the server with the new public key, and discarding the old public key. This ensures a seamless transition to the new passkey while maintaining the security and integrity of the user’s account.

Using Passkeys in WebView

Integrating passkey authentication within a WKWebView web view involves configuring the service’s relying party identifier as an associated domain in the app.

After completing the implementation of Passkeys, if you see Open “Password Options” like the screenshot below, you have to enable Passkeys from Passwords in your iPhone.

“Subsequently, with the Passkeys setting enabled, you will be presented with the following screenshot, facilitating the use of Passkeys for logging in or registering within the current application.”

Conclusion

By mastering passkey authentication, developers can enhance the security and usability of their iOS applications. With a thorough understanding of passkey implementation, developers can create seamless authentication experiences while ensuring robust security measures.

--

--

Batikan Sosun
Sahibinden Technology

Tweeting tips and tricks about #swift #xcode #apple Twitter @batikansosun Weekly Swift Blogging