Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How I got a Yubikey working with a Dvorak keyboard and Karabiner-Elements

How I got a Yubikey working with a Dvorak keyboard and Karabiner-Elements

I needed to set up a new Yubikey device, which plugs into my Mac laptop via USB-C and injects one-time codes by pretending to be a keyboard.

Problem: I use Dvorak... so the Yubikey codes were coming through incorrectly and failing to work.

https://superuser.do/2014/10/22/yubikey-support-for-non-qwerty-keyboard-layouts-on-mac-os-x/ has a recipe for fixing this using Karabiner. But... those instructions are for an older Karabiner which is configured using XML files.

The latest Karabiner - Karabiner-Elements - uses a JSON configuration instead.

Here's how I got it working:

  1. Installed Karabiner Elements 12.1.0 from https://pqrs.org/osx/karabiner/

  2. Launched Karabiner Elements for the first time (to ensure it would create its config files). Enabled it for the Yubikey in devices:

2018-10-30 at 1 55 pm

  1. Added a single key mapping specific to the Yubijey, in order to see how that looks in the config:

2018-10-30 at 2 11 pm

  1. Opened up the freshly generated ~/.config/karabiner/karabiner.json file to see what it looks like.

  2. Rebuilt the JSON section for the "simple_modifications" for that keyboard, starting with the XML example here: https://gist.github.com/sudowork/c7f182752a929d08a5ac - the hardest part was figuring out the keywords for non-alphanumeric-characters - I ended up consulting the Karabiner source code for those: https://github.com/tekezo/Karabiner-Elements/blob/d9cdf3312d3aa2f9887fd270a59e30f9670fc39c/src/share/types.hpp#L231-L448

The JSON is attached to this gist.

  1. Saved the new JSON in ~/.config/karabiner/karabiner.json. Useful tip: just hitting "save" on that file causes Karabiner to refresh its configuration - and the "Log" tab in the UI is really helpful here as it will directly display any validation errors in the JSON.

2018-10-30 at 2 26 pm

I tested the Yubikey in a text file, by running it in Dvorak and QWERTY mode and with and without the Karabiner modifications enabled. This gave me confidence that it was doing the right thing.

And... it worked! I can now use my Yubikey to sign in even though my regular keyboard layout is Dvorak.

{
"global": {
"check_for_updates_on_startup": true,
"show_in_menu_bar": true,
"show_profile_name_in_menu_bar": false
},
"profiles": [
{
"complex_modifications": {
"parameters": {
"basic.simultaneous_threshold_milliseconds": 50,
"basic.to_delayed_action_delay_milliseconds": 500,
"basic.to_if_alone_timeout_milliseconds": 1000,
"basic.to_if_held_down_threshold_milliseconds": 500
},
"rules": []
},
"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": "open_bracket"
},
"to": {
"key_code": "hyphen"
}
},
{
"from": {
"key_code": "close_bracket"
},
"to": {
"key_code": "equal_sign"
}
},
{
"from": {
"key_code": "c"
},
"to": {
"key_code": "i"
}
},
{
"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": "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"
}
},
{
"from": {
"key_code": "b"
},
"to": {
"key_code": "n"
}
}
]
},
{
"disable_built_in_keyboard_if_exists": false,
"fn_function_keys": [],
"identifiers": {
"is_keyboard": true,
"is_pointing_device": false,
"product_id": 632,
"vendor_id": 1452
},
"ignore": true,
"manipulate_caps_lock_led": true,
"simple_modifications": []
}
],
"fn_function_keys": [
{
"from": {
"key_code": "f1"
},
"to": {
"consumer_key_code": "display_brightness_decrement"
}
},
{
"from": {
"key_code": "f2"
},
"to": {
"consumer_key_code": "display_brightness_increment"
}
},
{
"from": {
"key_code": "f3"
},
"to": {
"key_code": "mission_control"
}
},
{
"from": {
"key_code": "f4"
},
"to": {
"key_code": "launchpad"
}
},
{
"from": {
"key_code": "f5"
},
"to": {
"key_code": "illumination_decrement"
}
},
{
"from": {
"key_code": "f6"
},
"to": {
"key_code": "illumination_increment"
}
},
{
"from": {
"key_code": "f7"
},
"to": {
"consumer_key_code": "rewind"
}
},
{
"from": {
"key_code": "f8"
},
"to": {
"consumer_key_code": "play_or_pause"
}
},
{
"from": {
"key_code": "f9"
},
"to": {
"consumer_key_code": "fastforward"
}
},
{
"from": {
"key_code": "f10"
},
"to": {
"consumer_key_code": "mute"
}
},
{
"from": {
"key_code": "f11"
},
"to": {
"consumer_key_code": "volume_decrement"
}
},
{
"from": {
"key_code": "f12"
},
"to": {
"consumer_key_code": "volume_increment"
}
}
],
"name": "Default profile",
"selected": true,
"simple_modifications": [],
"virtual_hid_keyboard": {
"country_code": 0
}
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment