Have you thought about scanning a YubiKey NFC in your Flutter app? I know I have! I wrote this to share my journey on how this can be achieved with minimal effort and full understanding on your part 😎 And without the help of ChatGPT! 😲
What is a YubiKey?
A YubiKey is a hardware authentication device that can be used to authenticate a user and protect access to a service or device. This device is usually used with 2FA to prevent phishing. When the device is authenticated, since the YubiKey will contain a unique cryptographic key-pair, we always know that the user who’s authenticating is present when they use it. Only the user has access to this key, and it’s actually on their person. For more info please checkout the yubico website.
What is NFC?
NFC stands for Near Field Communication device and is a scanner that can read / write data to and from NFC enabled devices. NFC is a type of wireless communication technology that allows two devices to communicate with each other when they are brought into close proximity. In relation to the YubiKey, the YubiKey NFC has a readable tag on the device, so with a mobile device that has NFC enabled, we can read this key and successfully authenticate.
Alrighty, now that I’ve dumped a bit of knowledge onto you, let’s dive in!
The device I will be using for this walkthrough is an iPhone 12, which comes standard with NFC built in. I will have to cover Android phones in another article when I can find an android phone that supports NFC.
To note, you will also need an Apple Developer account since we need to run the app on our phone and not the emulator to test. If you do not have one yet, please visit https://developer.apple.com/programs/enroll/ for more info on this.
This package will allow you to use your device’s NFC Tag Reader, but your device must have the ability to do so. I highly suggest you search to see if your device has the capability of reading NFC tags.
As per the package’s requirements, we’re going to have to add a few things:
- Near Field Communication Tag Reader Session Formats Entitlements
- A list of FeliCa system codes that the app supports
- A list of application identifiers that the app supports
Near Field Communication Entitlements
To add an entitlement, there’s some helpful documentation on this via https://help.apple.com/xcode/mac/current/#/dev88ff319e7. I highly recommend browsing through here as well for some additional treasures of information.
I will walk you through this as well as best as I can. I am using Xcode v14.1 for this. Open Xcode, then in File click Open again to select a workspace. In our project there is an folder called ios. Open that folder and find the Runner.xcworkspace file. Click to open.
Once opened you will see our project in Xcode. Click Runner in the top left side menu to open additional options.
Next click Signing & Capabilities
Next click the + Capabilities button below Signing & Capabilities
A menu should pop up with a list of capabilities. Search for Near and the Near Field Communication Tag Reading capability should pop up.
Select this option and you should see this added to your list of capabilities.
This is pretty easy and straight forward. We’re going to add a description as to why we’re going to be using the NFC reader in our Info.plist.
To do this you have 2 options. Use Xcode to add to your Info.plist or open the file in VSCode and add it manually.
Here below I’ve used Xcode to add this and my description is Scanning a key as the value. When you enter the a key use NFCReaderUsageDescription and it will change to what you see below Privacy — NFC Scan Usage Description.
Here you can add it manually as well in the Info.plist
Adding App support Codes
We will need to add support codes for the following keys to our Info.plist:
For this I would copy and paste the following and add it to your Info.plist manually. There are a lot of codes here, but adding these codes will enable the scanning for the nfc_manager package.
For a list of full codes for the select-identifiers key use the following repo here.
Coding the UI
Now we will need to create a simple UI with a button to begin the scanning process.
I’ve started with just a simple scaffolding of a basic project. We will start with dropping in a column and a button:
Then adding the functionality for the button:
The _startNFCScanSession method will initiate the scan. Here we pass in pollingOptions, specifically NfcPollingOption.iso14443. A YubiKey uses ISO 14443, so we will need to enable this polling option to read it.
The onDiscover property will accept a function with an NfcTag as an argument being passed in. Whenever the scanner picks up a tag, it will use this function as a callback and we can preform some logic here as well as stop the scanning.
_stopNFCScanSession will basically stop the scan session because we have successfully scanned the tag.
Run the app on your phone
If we run what we have so far on our phone, our app so far should look something like this:
Pretty simple! And when we press the button Start Scanning you should get this bottom sheet slide up and say “Ready to Scan”:
The device is ready to scan the NFC tag now which is located on your YubiKey device.
Upon successfully scanning a YubiKey, _stopNFCScanSession will be executed and you should see the following:
Scanning the key
Sometimes scanning the actual YubiKey can require a little bit of finesse depending on your device. I’m using an iPhone 12 and I have to place the key right next to my camera on the top left of the phone. Depending on where you NFC scanner is located on the device is where you’ll have to hold it. Often holding it for a few seconds and then moving it will help till you finally land it in the perfect spot to scan.
For the GitHub repo with full code please checkout this repo.
Also feel free to reach out anytime via LinkedIn as well for any questions you might have.
In a future article we will decode this key when it authenticates to actually log into an app on our mobile phone. Stay tuned for this hopefully soon!