This is a JavaCard applet that emulates the HMAC challenge-response functionality of the Yubikey NEO/4. It presents the same interface that a real Yubikey presents over CCID (i.e. this applet does not have any HID features).
The goal is to be able to write applications that use the HMAC-SHA1 Challenge-Response mode of the Yubikey, and have a JavaCard with this applet be a drop-in replacement.
What works:
-
HMAC-SHA1 challenge response, in HMAC_LT64 mode
-
Setting configuration using
CMD_SET_CONF_{1,2}
-
Using the protection access code to prevent accidental slot overwrite
The pre-built .cap
files for each release can be found on the
project release page.
You can use the
Global Platform command-line
tool (gp
) to upload the applet to your JavaCard:
$ gp -install YkOtpApplet.cap CAP loaded
If installed on a Yubikey, you can program the applet with an HMAC secret using yktool:
$ yktool list Yubikeys available: - Yubikey 4 #279305487 v4.0.0 $ echo 'b6e3f555562c894b7af13b1db37f28deff3ea89b' | yktool program hmac 1 -x -X Programmed slot 1 ok $ printf 'aaaa' | yktool hmac 1 -x 72:7E:C8:E8:15:EE:C5:32:8F:9D:9C:BE:5E:F2:4E:A8:36:D7:CE:56
If you install the applet to another JavaCard without HID capabilities, that tool won’t detect your card as a Yubikey. You can program a secret by sending the correct ADPU sequence to your card. A helper script to generate those ADPUs is included in the repository:
$ cat /dev/random | ./show_initalization_command.py opensc-tool -s 00A4040007A000000527200100 -s 0001030034000000000000000000000000000000001B1AECF9000077C051BAFD8E996FEED70C1384BEB94E0000000000000000402600000000
The script must be fed with exactly twenty bytes of keying material - the
HMAC secret for the slot. If you have the secret in hex form you can use
xxd -r -p
to convert it to binary.
Sending these two ADPUs (one to select the correct applet and one to program a slot config) to the card will initialize the applet. You can send ADPUs with GlobalPlatformPro, OpenSC, or the JavaCard tool of your choice.
See the contents of the Python script to set a slot protection ("access") code.
We use ant-javacard for builds.
$ git clone https://github.com/arekinath/YkOtpApplet ... $ cd YkOtpApplet $ git submodule init && git submodule update ... $ export JC_HOME=/path/to/jckit-2.2.2 $ ant
The capfile will be output in the ./bin
directory, along with the .class
files (which can be used with jCardSim).