Setup OTP / challenge-response for KeePassXC

Since KeePassXC 2.7.6 the nitrokey is supported as an additional factor to unlock the database. As I understand from the comments, an OTP / challenge-response must be set up on the Nitrokey. As an example, the following command is given to create the challenge-response:

nk3 secrets add-challenge-response 2 ABCDEFGHIJKLMNOPQRSTUVWXYZ234567

The output of the help from mk3 is very poor
nitropy nk3 secrets add-challenge-response --help


Command line tool to interact with Nitrokey devices 0.4.39
Usage: nitropy nk3 secrets add-challenge-response [OPTIONS] {1|2} SECRET

  Register Challenge-Response Credential.

  --help  Show this message and exit.

I assume that the string given in the example at the end of the above command is needed to create the OTP / challenge-response. The number {1|2} probably indicates the solt in which the created code is stored.

Currently, I have not found any meaningful instructions for the command.
Can you help me there?

I use a Yubikey (HMAC-SHA1) as a second factor for the KeePassXC database.
I still have the SecretKey as a twenty digit hex string, can I use this to create the secret key of my Nitrokey (pass it to the command above) and is the created key then compatible (the same)?

What information do you think is missing in the CLI help text?

Your assumption is correct. The secret is required in base32 format as with YK. Here is the information directly from the code:

    def register_yk_hmac(self, slot: int, secret: bytes) -> None:
        Register a Yubikey-compatible challenge-response slot.
        @param slot: challenge-response slot
        @param secret: the secret


According the Grand Unified Theory of Documentation, you might want to checkout this well written tutorial?

Hello @nku,

thank you for your answer and the link to the detailed and beautiful tutorial!

I miss more information about the parameters e.g.:

Command line tool to interact with Nitrokey devices 0.4.39
Usage: nitropy nk3 secrets add-challenge-response [OPTIONS] {1|2} SECRET

- {1|2} corresponds to the slot in which the HMAC-SHA1 key is stored
- SECRET is a password that is exactly 20 bytes long

  Register Challenge-Response Credential.

  --help  Show this message and exit.
1 Like

The Yubikey use to create the HMAC-SHA1 a 20 bytes Hex secret key e.g.
ce f8 d6 f4 8d 5b d5 dc c2 23 79 32 a7 a6 7e f2 bf c4 ed be.

How can I transform this 20 bytes Hex to create the SECRET for the Nitrokey command?

nitropy nk3 secrets add-challenge-response

This is the base32 command shown in the linked tutorial that converts the hex values.

xxd -r -p hexinput.txt output.bin
cat output.bin |base32

To create the challenge-response I did following steps:

  1. I create a hexinput.txt with the 20 bytes hex of the Yubikey secret without spaces.
    echo "cef8d6f48d5bd5dcc2237932a7a67ef2bfc4edbe

  2. Convert the text file to a bin file.
    xxd -r -p ./hexinput.txt out.bin

  3. Output the bin.file as base32
    cat out.bin | base32

  4. Copy the output from previous command as to create the challenge response
    itropy nk3 secrets add-challenge-response 2 <my secret>

Once I have solved the problem and the Nitrokey is recognized by KeePassXC, I will see if I could create a backup of my Yubikey. Then I will report back here.


In the meantime, I was able to test the Nitrokey with KeePassXC. With the procedure described above, a backup of the YubiKey HMAC-SHA1 is created. The KeePassXC database can now be opened with the YubiKey as well as with the Nitrokey. The only difference is that the Nitrokey does not require finger activation.

Can you create a hex for Nitrokey without a Yubikey?

You could use arbitrary data and generate a 20 bytes SHA-1 hash.


openssl rand -hex 10

If you don’t have a Yubikey, you don’t need a hex string.
As @nku explained, a twenty digit random value converted to a SHA-1 hash with base32 is sufficient.

E.g. like this (source: comment from Anonymous on 22. August 2023 - 19:16):

Generate a 20-byte random string with:
dd if=/dev/urandom of=/tmp/nk bs=20 count=1

Encode this and add to your nitrokey in a slot (slot 2 here):
nitropy nk3 secrets add-challenge-response 2 $(base32 /tmp/nk)
1 Like


Indeed having better parameters info would make sense here.

Regarding the random data, here is one of the commands to get it from Nitrokey 3:

$ nitropy nk3 rng