Using Yubikey on macOS with Colemak or other "weird" keyboard layouts

I just got a Yubikey for security at work. It’s a neat little device, and the way it sends one time passwords to your computer is by presenting as a vanilla USB keyboard and sending keystrokes. Pressing its single button types out a fresh one time password.

Unfortunately, as a keyboard, it’s subject to keyboard layout interpretation, and whilst 99% of the Latin-alphabet-using world use inefficient ol’ QWERTY, I ‘upgraded’ to Colemak some years ago. It took a lot of debugging to figure this out - my Yubikey generated working codes on my colleague’s computer but not-working ones on mine.

This isn’t the first time I’ve felt discriminated against due to my keyboard layout 😂

After a web search I found this article by Kevin Gao in 2014 with the same problem. This article is basically an update on how to do the same thing in September 2018.

Firstly, to do the remapping, you’ll need Karabiner Elements, the open source key re-mapper for macOS. I install it with brew cask install karabiner-elements.

Open it with the Yubikey plugged in and it’ll show up as a device:

Yubikey device on Karabiner-Elements

This means it will now also be saved in the configuration file ~/.config/karabiner/karabiner.json.

Shut down Karabiner-Elements temporarily, and edit that file to add the below reverse mapping. This is for Colemak, and I adapted it from a linked XML file for the original Karabiner app in the aforementioned post. Further below I’ve posted the one for Dvorak, and if you need your own it’s not much work to figure out a reverse mapping back to QWERTY.

Beware the snippet below includes the entirety of my devices list - yours might have other devices, or your Yubikey might vary by product_id, or maybe vendor_id (?).

"devices": [
    {
        "disable_built_in_keyboard_if_exists": false,
        "fn_function_keys": [],
        "identifiers": {
            "is_keyboard": true,
            "is_pointing_device": false,
            "product_id": 1031,
            "vendor_id": 4176
        },
        "ignore": false,
        "manipulate_caps_lock_led": false,
        "simple_modifications": [
            {"from": {"key_code": "f"}, "to": {"key_code": "e"}},
            {"from": {"key_code": "p"}, "to": {"key_code": "r"}},
            {"from": {"key_code": "g"}, "to": {"key_code": "t"}},
            {"from": {"key_code": "j"}, "to": {"key_code": "y"}},
            {"from": {"key_code": "l"}, "to": {"key_code": "u"}},
            {"from": {"key_code": "u"}, "to": {"key_code": "i"}},
            {"from": {"key_code": "y"}, "to": {"key_code": "o"}},
            {"from": {"key_code": "r"}, "to": {"key_code": "s"}},
            {"from": {"key_code": "s"}, "to": {"key_code": "d"}},
            {"from": {"key_code": "t"}, "to": {"key_code": "f"}},
            {"from": {"key_code": "d"}, "to": {"key_code": "g"}},
            {"from": {"key_code": "n"}, "to": {"key_code": "j"}},
            {"from": {"key_code": "e"}, "to": {"key_code": "k"}},
            {"from": {"key_code": "i"}, "to": {"key_code": "l"}},
            {"from": {"key_code": "k"}, "to": {"key_code": "n"}},
            {"from": {"key_code": "o"}, "to": {"key_code": "semicolon"}},
            {"from": {"key_code": "semicolon"}, "to": {"key_code": "p"}}
        ]
    }
],

If you’re using Dvorak use this:

"devices": [
    {
        "disable_built_in_keyboard_if_exists": false,
        "fn_function_keys": [],
        "identifiers": {
            "is_keyboard": true,
            "is_pointing_device": false,
            "product_id": 1031,
            "vendor_id": 4176
        },
        "ignore": false,
        "manipulate_caps_lock_led": false,
        "simple_modifications": [
            {"from": {"key_code": "b"}, "to": {"key_code": "n"}},
            {"from": {"key_code": "c"}, "to": {"key_code": "i"}},
            {"from": {"key_code": "close_bracket"}, "to": {"key_code": "equal_sign"}},
            {"from": {"key_code": "comma"}, "to": {"key_code": "w"}},
            {"from": {"key_code": "d"}, "to": {"key_code": "h"}},
            {"from": {"key_code": "period"}, "to": {"key_code": "e"}},
            {"from": {"key_code": "e"}, "to": {"key_code": "d"}},
            {"from": {"key_code": "equal_sign"}, "to": {"key_code": "close_bracket"}},
            {"from": {"key_code": "f"}, "to": {"key_code": "y"}},
            {"from": {"key_code": "g"}, "to": {"key_code": "u"}},
            {"from": {"key_code": "h"}, "to": {"key_code": "j"}},
            {"from": {"key_code": "i"}, "to": {"key_code": "g"}},
            {"from": {"key_code": "j"}, "to": {"key_code": "c"}},
            {"from": {"key_code": "k"}, "to": {"key_code": "v"}},
            {"from": {"key_code": "l"}, "to": {"key_code": "p"}},
            {"from": {"key_code": "hyphen"}, "to": {"key_code": "quote"}},
            {"from": {"key_code": "n"}, "to": {"key_code": "l"}},
            {"from": {"key_code": "o"}, "to": {"key_code": "s"}},
            {"from": {"key_code": "open_bracket"}, "to": {"key_code": "hyphen"}},
            {"from": {"key_code": "p"}, "to": {"key_code": "r"}},
            {"from": {"key_code": "q"}, "to": {"key_code": "x"}},
            {"from": {"key_code": "quote"}, "to": {"key_code": "q"}},
            {"from": {"key_code": "r"}, "to": {"key_code": "o"}},
            {"from": {"key_code": "s"}, "to": {"key_code": "semicolon"}},
            {"from": {"key_code": "semicolon"}, "to": {"key_code": "z"}},
            {"from": {"key_code": "slash"}, "to": {"key_code": "open_bracket"}},
            {"from": {"key_code": "t"}, "to": {"key_code": "k"}},
            {"from": {"key_code": "u"}, "to": {"key_code": "f"}},
            {"from": {"key_code": "v"}, "to": {"key_code": "period"}},
            {"from": {"key_code": "w"}, "to": {"key_code": "comma"}},
            {"from": {"key_code": "x"}, "to": {"key_code": "b"}},
            {"from": {"key_code": "y"}, "to": {"key_code": "t"}}
        ]
    }
],

After saving, restart Karabiner-Elements and try pressing on your Yubikey. Since the first 12 characters in each one time password are the same, you can compare them with those generated on a QWERTY computer to check it’s working.

You’ll also want to make sure Karabiner-Elements is set to run at login so the remapping is permanent.

Enjoy!


Tags: