简体中文 / [English]


DIY Open-Source Yubikey for 30 RMB (Supports FIDO2 Hardware Security Key)

 

This article is currently an experimental machine translation and may contain errors. If anything is unclear, please refer to the original Chinese version. I am continuously working to improve the translation.

Introduction

Cloudflare’s YubiKey promotion a while back sparked a small wave of interest in hardware security keys, with many people grabbing YubiKeys at discounted prices through international forwarding services. But two years have passed, and there hasn’t been another deal like it—the current price for in-stock units in China remains high (~500 RMB).

Moreover, since YubiKey firmware is completely non-upgradable, buying older models from unofficial channels isn’t ideal. These older keys can’t benefit from the latest security patches or feature updates. In fact, the batch sold during that promotion has already been found to have a security vulnerability, and users have no option but to buy a new one—there’s no way to fix it otherwise.


Until recently, I’ve been relying on Windows Hello (face/PIN) as my WebAuthn authenticator, and storing SSH private keys in the TPM. These methods are hardware-backed by the TPM and theoretically offer security comparable to a dedicated FIDO2 hardware key.

But what I once considered an advantage—not needing extra hardware—has now become a drawback. As mentioned in that article, I’ve recently started needing mobile work setups where I don’t want to carry my full laptop, just a compact security key.

So here we are: I went looking for a YubiKey alternative that’s easy to buy and affordable, and built my own portable hardware key.

Hardware Selection

The functionality of hardware keys is fairly similar (all support the FIDO2 protocol), so the main concern is security—specifically, whether stored keys can be extracted. Besides the famous (and expensive) YubiKey, my initial search led me to Google’s open-source OpenSK and Tsinghua University’s CanoKeys.

OpenSK

OpenSK uses the nRF52840 platform. You can find related hardware like nRF52840-MDK USB Dongle on Taobao, but Google explicitly states that OpenSK is not recommended for daily use. I couldn’t find much information about its security—especially whether it protects against key extraction upon physical access.

CanoKeys

CanoKeys supports both nRF and STM32 platforms, but the official documentation clearly states that anyone with physical access to the device can extract the plaintext keys, making it unsuitable for regular use. The official store on Taobao does sell secure versions using the HED CIU98320B chip: CanoKey Pigeon and CanoKey Canary.

Pico Keys

Both of the above options cost at least 100 RMB. Then I stumbled upon the Pico Keys project on GitHub, which became the focus of this article. It currently supports several dev boards based on ESP32S3, RP2040, and RP2350. (These RP chips are used in the Raspberry Pi Pico and Raspberry Pi Pico 2, respectively.)

Beyond the Raspberry Pi chips offering many board options, high popularity, easy availability in China, and very low cost (~30 RMB), I came across the RP2350 Hacking Challenge while researching. Raspberry Pi offered a $20,000 prize to anyone who could bypass the RP2350’s Secure Boot and other protections to read data from its OTP (One-Time Programmable) region. In the end, four successful attacks used highly non-trivial techniques—and all winners received the prize.

I strongly agree with the closing statement in Raspberry Pi’s blog post:

All vendors have security vulnerabilities in their chips. We are unusual because we talk about them, and aim to fix them, rather than brushing them under the carpet. Security through transparency is here to stay.

Interestingly, the Pico Keys project leverages the RP2350‘s Secure Boot and OTP features to protect stored keys from being extracted or cloned during physical access. This gives me greater confidence in its security.

Hardware Purchase and Firmware Flashing

RP2350 is just the chip model—many dev boards use it. After some consideration, I chose the compact and portable Waveshare RP2350-One. This board is easily available on Taobao for around 30 RMB with free shipping. The Pico Keys project supports various other boards, so feel free to pick the one that’s easiest or cheapest to obtain.

The purchased Waveshare RP2350-One, roughly the size of a small USB drive. The exposed PCB can later be protected with transparent heat-shrink tubing—or maybe plastic wrap?The purchased Waveshare RP2350-One, roughly the size of a small USB drive. The exposed PCB can later be protected with transparent heat-shrink tubing—or maybe plastic wrap?

Flashing firmware onto the RP2350 is extremely simple: just hold the Boot button while plugging it into your computer. It will appear as a USB drive. Simply copy the .uf2 firmware file onto it, and it will automatically flash and reboot—no drivers or special tools needed, completely smooth.

The Waveshare RP2350-One is not yet officially supported by Pico Keys, but based on my testing, the firmware for the Raspberry Pico 2 works perfectly on this board. The only minor issue is that the LED won’t light up—but functionality remains unaffected. Just download the corresponding .uf2 file and flash it.


After flashing, you can enable Secure Boot and Secure Lock via the author’s online configuration tool, Pico Commissioner. The trade-off is that once enabled, the device can only run official Pico Keys firmware. But the benefit is enhanced security, so it’s highly recommended before putting it into regular use. (If you want both DIY flexibility and security, consider self-signing.)

As a fun side note, I also used the tool to spoof the vendor as Yubikey 4/5 and set the product name to yubico yubikey, allowing me to use Yubico’s official ykman management tool.


Side note: The author provides a special firmware for wiping all data. Use it if you ever need to reset the key to factory settings.

Functionality Testing

Let’s test the features of this DIY security key.

FIDO2

It supports WebAuthn for authentication, either as a passwordless Passkey or as a second factor in 2FA.

Search for "FIDO2 Test" and you’ll find many websites to test online. On first registration, you’ll need to set a PIN.Search for "FIDO2 Test" and you’ll find many websites to test online. On first registration, you’ll need to set a PIN.

You can check the key’s status using the ykman tool:

1
2
3
4
5
6
PS C:\> ykman list
YubiKey 5A (6.2.0) [OTP+FIDO+CCID] Serial: 272681xxxx
PS C:\> ykman fido info
PIN: 8 attempt(s) remaining
Minimum PIN length: 4
Enterprise Attestation: Disabled

By default, the PIN allows only 8 attempts: after every 3 failed tries, the key is temporarily blocked and requires reinsertion to continue. After 8 total failed attempts, the key is permanently blocked and must be reset—this erases all stored credentials. (The hardware itself remains usable.)

FIDO2 can also be used for SSH keys:

1
2
3
4
5
6
7
8
9
lyc8503@Laptop MINGW64 ~
$ ssh-keygen -t ed25519-sk
Generating public/private ed25519-sk key pair.
You may need to touch your authenticator to authorize key generation.
Enter file in which to save the key (/c/Users/lyc8503/.ssh/id_ed25519_sk):
Enter passphrase for "/c/Users/lyc8503/.ssh/id_ed25519_sk" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/lyc8503/.ssh/id_ed25519_sk
Your public key has been saved in /c/Users/lyc8503/.ssh/id_ed25519_sk.pub

Keys generated with ssh-keygen -t ed25519-sk require both the hardware key and the id_ed25519_sk file to function—adding an extra layer of security. Neither the key nor the file alone is sufficient for SSH access.

If you want to carry only the key and use it anywhere, generate a resident key with ssh-keygen -t ed25519-sk -O resident. Then, on any machine, run ssh-keygen -K to retrieve the public and private keys. (On Windows, this command may require administrator privileges.)

(P.S. There are other hardware-backed SSH methods, so you might see alternative setups—but they tend to be more complex.)

OATH

Testing the most common use case—TOTP—you can store TOTP secrets in the hardware and generate 6-digit codes:

1
2
3
4
5
6
7
8
9
10
PS C:\> ykman oath info
OATH version: 6.2.0
Password protection: disabled
PS C:\> ykman oath accounts add test
Enter a secret key (base32): NE24O5QURZMW7LCXD2RVMGIPCZKQPQOJ
OATH account added.
PS C:\> ykman oath accounts list
test
PS C:\> ykman oath accounts code test
test 546226

Once stored, the TOTP secret cannot be retrieved, but codes can be safely generated. For extra security, you can set a password for OATH—requiring a password each time a code is generated. (This is independent of the FIDO PIN.)

1
2
3
4
5
6
7
PS C:\> ykman oath access change
Enter the new password:
Repeat for confirmation:
Password updated.
PS C:\> ykman oath accounts code test
Enter the password:
test 930200

PIV & OpenPGP

Official YubiKeys pack all features into one device, but the Pico Keys author has split them into separate projects. If needed, you must flash pico-opengpg separately. Since I don’t currently need this functionality, I won’t go deeper into it here.

Summary

And just like that, we now have an open-source, secure, upgradable, and incredibly affordable hardware security key 🎉

This article is licensed under the CC BY-NC-SA 4.0 license.

Author: lyc8503, Article link: https://blog.lyc8503.net/en/post/diy-fido-key/
If this article was helpful or interesting to you, consider buy me a coffee¬_¬
Feel free to comment in English below o/