-*- mode: org; coding: utf-8 -*- * How Yubikey is used in Password Safe To get basic understanding of HMAC, see my blog post about it: https://yurichev.org/LEA/ Yubikey with OTP feature must be used for Password Safe. ** Programming Yubikey with command line utilities Ubuntu packages we will need: yubikey-manager, yubikey-personalization. Run: #+BEGIN_TEXT % ykpersonalize -2 -ochal-resp -ochal-hmac -ohmac-lt64 -ochal-btn-trig -oserial-api-visible Firmware version 5.4.3 Touch level 770 Program sequence 5 Configuration data to be written to key configuration 2: fixed: m: uid: n/a key: h:3349d48d5c533045a70a0d576437f225803af23f acc_code: h:000000000000 OATH IMF: h:0 ticket_flags: CHAL_RESP config_flags: CHAL_HMAC|HMAC_LT64|CHAL_BTN_TRIG extended_flags: SERIAL_API_VISIBLE Commit? (y/n) [n]: y #+END_TEXT The (HMAC) key is generated randomly each time. The second slot must be already programmed after that: #+BEGIN_TEXT % ykman otp info Slot 1: empty Slot 2: programmed #+END_TEXT If you want to setup a specific HMAC key (like I do, for the sake of experiment), run: #+BEGIN_TEXT % ykman otp chalresp -t 2 00112233445566778899aabbccddeeff00112233 Program a challenge-response credential in slot 2? [y/N]: y challenge-response credential stored in slot 2. #+END_TEXT But many Password Safe users will be fine with randomly generated HMAC key --- either by ykpersonalize tool or by Password Safe "Set Yubikey" feature. ** Creating Password Safe database, protected by Yubikey (This part is applicable to Password Safe v1.26 (October-2026). Some things may change in further versions.) Yubikey must be initialized before database creating. Either using command line utilities (see above) or using Password Safe: open any database (or create new) and click on Manage -> Yubikey -> Set Yubikey. A long hexadecimal string will be generated (HMAC key) that can be written to Yubikey instantly. That HMAC key will also be written to current database, so that it can be written to another Yubikey too (second, third...) That HMAC key can also be stored in some safe place, because if your Yubikey is lost, you will not be able to decrypt database. (Of course, that place have to be far from the database itself.) Maybe even printed and stashed in safe place. If you try to create database with Yubikey that has empty second slot, Password Safe may display "Timeout - please try again" red message. Now when you create a database with initialized Yubikey, the entered master password becomes HMAC-SHA1(entered master password), and HMAC-SHA1 is calculated via Yubikey, using stored HMAC key in the second slot. (By the way, master password to be entered may also be empty.) Also, needless to say, the master password in Password Safe encoded in UTF-16 encoding (Windows heritage?) ** Accessing Yubikey without Password Safe We can manually calculate HMAC-SHA1 for the "abc" password (0x61...0x63 are ASCII codes for 'a'...'c'): #+BEGIN_TEXT % ykman otp calculate 2 "6100620063" Touch your YubiKey... 0900a4835f4795159eedcb92b9aa98a27c94cb38 #+END_TEXT The resulting hash ("0900a4835f4795159eedcb92b9aa98a27c94cb38") can be used instead of master password in Password Safe, with YubiKey disconnected! However, as you see, last byte is 63, but UTF-16 encoding for "abc" would be "610062006300". It's because HMAC_LT64 option is used here: #+BEGIN_TEXT [-]hmac-lt64 Calculate HMAC on less than 64 bytes input. Whatever is in the last byte of the challenge is used as end of input marker (backtracking from end of payload). #+END_TEXT ( https://linux.die.net/man/1/ykpersonalize ) Also, access YubiKey using Python (YubiKey is also must be touched after run): #+BEGIN_TEXT #!/usr/bin/env python3 # Ubuntu: sudo apt install python3-yubico import yubico import binascii YK=yubico.find_yubikey(debug=3) password=b"a\0b\0c" response=YK.challenge_response(password, slot=2) print (binascii.hexlify(response).decode('utf-8')) #+END_TEXT The resulting hash is also (correct) 0900a4835f4795159eedcb92b9aa98a27c94cb38. ** Opening Yubikey-protected Password Safe database without Yubikey If you have your HMAC key, you can generate master password for Password Safe database, without Yubikey: #+BEGIN_TEXT #!/usr/bin/env python3 import hashlib, hmac, binascii password=b"a\0b\0c" key=binascii.unhexlify("00112233445566778899aabbccddeeff00112233") m=hmac.new(key, digestmod=hashlib.sha1) m.update(password) HMAC=m.digest() print (binascii.hexlify(HMAC).decode("utf-8")) #+END_TEXT The resulting hash is also (correct) 0900a4835f4795159eedcb92b9aa98a27c94cb38. This can be used as a fail-safe method to open your Password Safe database in case if your Yubikey is lost. But do not forget to store your HMAC key securely (and not in Password Safe database --- how would you open it?) ** So why using Yubikey, if anyone can calculate HMAC using a small Python script? HMAC stored in Yubikey cannot be extracted from it --- at least, theoretically. Yubikey cannot be cloned (so you probably should program several keys, and one of them to be kept in safe place as backup). (Of course, bugs and vulns can be present in Yubikey too, but developers try hard to protect keys from bugs.) Yubikey is a cryptoprocessor --- it can work with your HMAC key within its boundaries, and that HMAC key never leaves Yubikey. Yubikey (as any other cryptoprocessor) cannot be stolen remotely by an attacker, while your Password Safe database and other files --- can be. Yubikey cannot be accessed by attacker remotely even if he/she is inside of your Unix computer: a key must be touched physically to proceed (this is indeed a protection against remote attackers). One thing to mention --- if you get used Yubikey that has already programmed second slot, a seller may know that HMAC key. Just to be safe, it should be reprogrammed with a random HMAC before use with Password Safe.