How to implement a CryptoTokenKit extension on iOS

In previous blog posts here and here, we’ve shared how you can use a YubiKey and its PIV Smart Card application together with the Yubico Authenticator app for iOS. Essentially, you can now use your YubiKey to authenticate in Safari and many other applications on iOS using certificate-based authentication backed by the PIV Smart Card application on a YubiKey. Check out the video below for details on how to do this.

One key feature we haven’t covered yet is how we implemented the CryptoTokenKit extension needed for this functionality. Searching the Internet gives very few clues and the documentation covering Apples CTK is pretty terse. The CTK extension itself has a few limitations making it difficult to deliver a good user experience, including:  

  1. The PIN input dialog. It will not display any error messages if the user enters the wrong PIN code – it will just display the PIN input dialog again. 
  1. A lack of NFC support in the CTK extension itself. This is crucial since we want to support both YubiKeys with a Lightning connector, as well as NFC enabled keys. 

Before we dive much further, let’s dive into an overview of iOS extensions and CTK extensions:

What is an iOS extension?

Extensions are embedded into the main application and in Xcode they are configured as separate targets. The extension and the main app run as separate processes and don’t share any memory. They can, however, access shared resources such as files and Keychain Access Groups.

How does the CryptoTokenKit extension work?

In our use case the CTK extension will get a request to sign a piece of data. The delegate method in the extension provides the public part of the client certificate to be used. It’s then up to the extension to figure out which private key to use, sign the data, and pass the signature back. iOS keeps track of linking client certificates to apps and their embedded CTK extensions.

Since NFC is not available in the CTK extension, the only way to communicate with a NFC YubiKey is via the main app which gives us full control over the UI to display error messages in a proper way. This points to a solution where both NFC and Lightning communication with the YubiKey is handled by the main app.

  • Opening the main application from the extension. The CTK extension is part of our application, but it’s actually started from browsers such as Safari. The first choice would be to create a custom URL scheme for our app and let the extension open that. Unfortunately there is no shared UIApplication instance in a CTK extension. This leaves us with popping a local notification from the extension and informing the user that they need to tap it to continue. Using a notification also makes it easy to pass on the data to be signed, which algorithm to use and some other information to the main app.
  • When the app is opened via the notification, it shows a custom view controller that handles PIN input and communication with the YubiKey. This is the easy part where we simply ask the user for their PIN code and sign the data using the correct private key on the YubiKey.

  • Sending the signature back to the CTK extension. The problem with not having shared memory between the CTK extension and the main app is still an issue but the UserDefault key value storage is a shared resource that both targets have access to. The main app writes the signature to UserDefault and encourages the user to tap the back button in the upper left corner to return to the originating app. 
  • While all this is going on in the main app, the CTK extension enters a loop where it polls for the signature in UserDefaults every second. Once the main app has written the data to the UserDefaults, the extension reads it and deletes the entry. The extension finally hands over the signature to the TKTokenSessionDelegate method and the user is now authenticated in a browser such as Safari.

Though this can become fairly complicated, the good news is that if you just want to add support for authentication in iOS using client certificates on a YubiKey you don’t have to implement all this. If your website already uses client certificates and YubiKeys for authentication, the only thing you need to do to enable this on iOS is installing the Yubico Authenticator.

Another use case could be embedding your website in a WKWebView. In this case, we’ve created an easy sample project below that will help you on our GitHub page. Check out the links below to give it a go and give us feedback on GitHub!

Yubico Authenticator

Source code: https://github.com/Yubico/yubioath-ios

App store: https://apps.apple.com/us/app/yubico-authenticator/id1476679808

Sample application

Sample code using a WKWebView together with the Yubico Authenticator

https://github.com/YubicoLabs/yubico-ctk-samples-ios

Talk to our teamTalk to our team

Share this article:


  • Goodbye master passwords: Dashlane and Yubico enhance credential vault encryption and login with YubiKeysAt Authenticate 2025 this week, the world’s leading experts on modern authentication and securing digital identities gathered, to discuss the future of secure authentication and achieving usable security across the account lifecycle. The message was clear: the future of phishing-resistant authentication is using passkeys for encryption, and the gold standard is device-bound passkeys – YubiKeys. […]Read morecredential vault encryptioncredential vault loginDashlanepartnerpasskey encryptionPRF
  • Piloting Europe’s future ID: Passkeys securing digital walletsOver the last several years, passkeys have become ubiquitous. They are available on every mobile platform, in every leading browser, as part of all major enterprise IAM solutions, and in most major cloud services. Until wwWallet came along, the only place where passkeys hadn’t yet made an impact is in the rapidly developing world of […]Read moredigital identity walletspasskeysSIROSwwWallet
  • We’re excited for what’s to come – meet us in-person to find out whyIt’s been a busy year for our team, filled with exciting company and product updates aimed at better serving our customers and helping them achieve cyber resilience as AI-driven phishing threats continue evolving globally. Between industry award recognitions and key new executive leadership hires to lead Yubico to its next stage of growth and a […]Read more
  • FIPS certified vs. FIPS compliant: What’s the real difference?“Is your MFA solution FIPS compliant, or is it certified?”  This is a question we hear a lot, and for good reason. In industries where security and compliance are critical (especially in government contracts), understanding the difference between FIPS certified and FIPS compliant isn’t just semantics – it can mean the difference between meeting requirements […]Read moreFIPSNIST