I’ve been banging my head against this issue as well. The tl;dr is that I believe the NFC interface on the Nitrokey 3A NFC is unusable, and every other FIDO2 NFC key I have performs better.
Nitrokey 3A NFC seems functional over USB HID, enough that I was able to run a firmware upgrade from v1.2.0 to v1.4.0 – but I have been unable to get it working reliably (ie: >90% success rate) over NFC (before or after the update) with anything but a Proxmark3.
Side note: there’s a bug in Proxmark’s CTAP2 implementation, where they don’t send Le
bytes for CTAP2 GetInfo, and then it gets stuck in an infinite loop. Nitrokey correctly follows the ISO7816-4 spec by treating that as Ne=0, whereas other keys follow the U2F spec’s incorrect description of ISO7816-4, and treat missing Le
bytes as Ne=256. Once PM3 sends Le=00
(Ne=256), Nitrokey works fine.
Other than the Proxmark, I’ve tried it with an ACR122T, ACR122T, ACR123U, iPhone SE 2022 and Pixel 3A. No amount of orientation changes or delicate movements makes things better.
The Nitrokey 3A NFC seems to have an extremely marginal NFC interface; on the occasion (less than 1% of the time) the ACR122T/U manages to get to SELECT
the CTAP2 applet (00a4040008a0000006472f000100
), further commands like CTAP2 GetInfo (80100000010400
) get no response or report “Removed Card”.
Plugging the Nitrokey into a USB powerbank (as suggested earlier in the thread) seems to make it more reliable (~10% success rate with ACR122T/U); but needs a hard power cycle after a transaction failure. I’m also measuring increased current draw from USB during operation (0.025W idle → 0.040W in use), which suggests that the processor is unable to harvest enough energy from the NFC field.
By comparison, all of the other NFC+USB FIDO2 tokens I have won’t even work over NFC if powered by USB. The fact that you’d even need a USB powerbank to run an NFC token is absurd… and makes me think that this is a fundamental design flaw.
The device won’t even work at all with an ACR123U (it detects the device, then the buzzer screams loudly as the device drops in and out), or the iPhone or Pixel.
For comparison, I have multiple NFC FIDO2 tokens from other vendors (Feitian, Hideez, Token2, Yubikey) and contactless smartcards which work just fine with all of those readers – they are not affected by orientation or even thick mobile phone cases – the difference is like night and day.
As a result, I believe it is reasonable to expect the Nitrokey 3A NFC to achieve similar performance, especially as the most expensive of those keys.
Here’s an example ISO14443A trace of a Nitrokey 3A NFC failure:
Start | End | Src | Data (! denotes parity error) | CRC | Annotation
------------+------------+-----+-------------------------------------------------------------------------+-----+--------------------
0 | 2368 | Tag |44 00 | |
11052 | 13516 | Rdr |93 20 | | ?
14720 | 20608 | Tag |88 1d 00 91 04 | |
41772 | 52300 | Rdr |93 70 88 1d 00 91 04 66 07 | | ?
53504 | 57024 | Tag |04 da 17 | |
66204 | 68668 | Rdr |95 20 | | ?
69872 | 75696 | Tag |49 67 00 00 2e | |
97052 | 107516 | Rdr |95 70 49 67 00 00 2e ae 17 | | ?
108784 | 112368 | Tag |20 fc 70 | |
120604 | 125308 | Rdr |e0 50 bc a5 | | ?
126576 | 134704 | Tag |05 78 91 78 00 3e 74 | |
3014220 | 3036268 | Rdr |02 00 a4 04 00 0b a0 00 00 03 08 00 00 10 00 01 00 11 | |
| | |bf | | SELECT FILE
3088544 | 3094432 | Tag |02 6a 82 93 2f | |
(intentional delay due to macOS PIV issue)
9817308 | 9836988 | Rdr |03 00 a4 04 00 08 a0 00 00 06 47 2f 00 01 00 f4 44 | | SELECT FILE
9859376 | 9872112 | Tag |03 55 32 46 5f 56 32 90 00 e0 b1 | |
10097628 | 10109308 | Rdr |02 80 10 00 00 01 04 00 44 a7 | | CTAP2 GetInfo request
10471984 | 10474352 | Tag |63 63 | |
10488924 | 10492476 | Rdr |c2 e0 b4 | | S-block ABORT req
10493744 | 10497264 | Tag |c2 e0 b4 | |
10554076 | 10557692 | Rdr |b2 67 c7 | | S-block
11302380 | 11305996 | Rdr |b3 ee d6 | | S-block
25906076 | 25907132 | Rdr |26 | | ?
25982108 | 25983164 | Rdr |26 | | ?
26480940 | 26481996 | Rdr |26 | | ?
26556588 | 26557644 | Rdr |26 | | ?
(PC/SC reports no response data)
And another vendor’s key, working fine:
Start | End | Src | Data (! denotes parity error) | CRC | Annotation
------------+------------+-----+-------------------------------------------------------------------------+-----+--------------------
0 | 2368 | Tag |42 00 | |
10908 | 13372 | Rdr |93 20 | | ?
14576 | 20464 | Tag |88 04 22 21 8f | |
41756 | 52220 | Rdr |93 70 88 04 22 21 8f 92 8b | | ?
53488 | 57008 | Tag |04 da 17 | |
69856 | 75744 | Tag |4a a4 5a 80 34 | |
97036 | 107500 | Rdr |95 70 4a a4 5a 80 34 f8 d7 | | SELECT FILE
108768 | 112352 | Tag |38 35 ec | |
124476 | 124892 | Rdr |01 | | ?
126800 | 145296 | Tag |0e 78 f7 b1 02 4a 43 4f 50 32 34 32 52 33 1b eb | |
3059772 | 3081820 | Rdr |02 00 a4 04 00 0b a0 00 00 03 08 00 00 10 00 01 00 11 | |
| | |bf | | SELECT FILE
3246608 | 3252496 | Tag |02 6a 82 93 2f | |
(intentional delay due to macOS PIV issue)
9861436 | 9881116 | Rdr |03 00 a4 04 00 08 a0 00 00 06 47 2f 00 01 00 f4 44 | | SELECT FILE
9950480 | 9963216 | Tag |03 55 32 46 5f 56 32 90 00 e0 b1 | |
10153660 | 10165340 | Rdr |02 80 10 00 00 01 04 00 44 a7 | | CTAP2 GetInfo request
10207760 | 10214928 | Tag |12 00 aa 01 83 66 55 32 46 5f 56 32 68 46 49 44 4f 5f | | GetInfo response
| | |32 5f 30 6c 46 49 44 4f 5f 32 5f 31 5f 50 52 45 02 82 | |
| | |6b 63 72 65 64 50 72 6f 74 65 63 74 6b 68 6d 61 63 2d | |
| | |73 65 63 72 65 74 03 27 fb | |
10481084 | 10484636 | Rdr |a3 6f c6 | | S-block WTX resp
10488976 | 10496144 | Tag |13 50 ee 04 1b ce 25 e5 4c db 8f 86 89 7f d6 41 84 64 | |
| | |04 a5 62 72 6b f5 62 75 70 f5 64 70 6c 61 74 f4 69 63 | |
| | |6c 69 65 6e 74 50 69 6e f5 75 63 72 65 64 65 6e 74 69 | |
| | |61 6c 4d 67 6d 74 50 fb 64 | |
10762172 | 10765724 | Rdr |a2 e6 d7 | | S-block ABORT resp
10770320 | 10771728 | Tag |02 72 65 76 69 65 77 f5 05 19 04 00 06 81 01 07 06 08 | |
| | |18 60 09 82 63 6e 66 63 63 75 73 62 0a 81 a2 63 61 6c | |
| | |67 26 64 74 79 70 65 6a 70 75 62 6c 69 63 2d 6b 65 79 | |
| | |90 00 4d 4f | |
22382892 | 22386508 | Rdr |b2 67 c7 | | S-block
22390784 | 22392192 | Tag |02 72 65 76 69 65 77 f5 05 19 04 00 06 81 01 07 06 08 | |
| | |18 60 09 82 63 6e 66 63 63 75 73 62 0a 81 a2 63 61 6c | |
| | |67 26 64 74 79 70 65 6a 70 75 62 6c 69 63 2d 6b 65 79 | |
| | |90 00 4d 4f | |
25442268 | 25445884 | Rdr |b2 67 c7 | | S-block
25450160 | 25451568 | Tag |02 72 65 76 69 65 77 f5 05 19 04 00 06 81 01 07 06 08 | |
| | |18 60 09 82 63 6e 66 63 63 75 73 62 0a 81 a2 63 61 6c | |
| | |67 26 64 74 79 70 65 6a 70 75 62 6c 69 63 2d 6b 65 79 | |
| | |90 00 4d 4f | |
28501660 | 28505276 | Rdr |b2 67 c7 | | S-block
28509552 | 28510960 | Tag |02 72 65 76 69 65 77 f5 05 19 04 00 06 81 01 07 06 08 | |
| | |18 60 09 82 63 6e 66 63 63 75 73 62 0a 81 a2 63 61 6c | |
| | |67 26 64 74 79 70 65 6a 70 75 62 6c 69 63 2d 6b 65 79 | |
| | |90 00 4d 4f | |
31561036 | 31564652 | Rdr |b2 67 c7 | | S-block
31568928 | 31570336 | Tag |02 72 65 76 69 65 77 f5 05 19 04 00 06 81 01 07 06 08 | |
| | |18 60 09 82 63 6e 66 63 63 75 73 62 0a 81 a2 63 61 6c | |
| | |67 26 64 74 79 70 65 6a 70 75 62 6c 69 63 2d 6b 65 79 | |
| | |90 00 4d 4f | |
34620428 | 34624044 | Rdr |b2 67 c7 | | S-block
34628320 | 34629728 | Tag |02 72 65 76 69 65 77 f5 05 19 04 00 06 81 01 07 06 08 | |
| | |18 60 09 82 63 6e 66 63 63 75 73 62 0a 81 a2 63 61 6c | |
| | |67 26 64 74 79 70 65 6a 70 75 62 6c 69 63 2d 6b 65 79 | |
| | |90 00 4d 4f | |
37680572 | 37684188 | Rdr |b2 67 c7 | | S-block
38428876 | 38432492 | Rdr |b3 ee d6 | | S-block
42075420 | 42076476 | Rdr |26 | | ?
Side note: macOS PIV issue: macOS will try to SELECT
the PIV applet (a000000308000010000100
) on smart card “insertion”, even when another application has an “exclusive” connection using the PC/SC API. Nitrokey (like other keys) correctly returns sw=6a82
(file not found), but if that command arrives after the SELECT
for the CTAP2 applet, Nitrokey will also deselect the FIDO2 applet (whereas other vendors keys do not). So if that arrives between a FIDO2 SELECT and further FIDO2 commands, Nitrokey will respond to CTAP2 GetInfo after PIV (80100000010400
) with sw=6a82
.
Annoyingly, the only way you can detect that issue is by running an RFID sniffer (like a Proxmark3), but the aforementioned marginal NFC antenna makes that harder to detect on Nitrokey.
Heads up for others testing: Unlike many other keys, the Nitrokey 3A NFC’s antenna is stuck to the case via a very thin ribbon cable (rather than being part of the main PCB).
I learned this trying to pull apart the Nitrokey to try to get the antenna closer to the reader, presuming it was printed on the PCB. While it was very easy to open the case, I damaged the ribbon cable on one unit by excessive force.
That may be repairable, but I don’t have the parts on me right now. But, it may be an opportunity to fashion a better antenna.