NK3 - Veracrypt keyfile accessible WITHOUT PIN entry

I have my Nitrokey 3 setup as OpenPGP card. Among other things, I wanted to store an VeraCrypt keyfile as described here: Hard Disk Encryption - Nitrokey Documentation

I installed OpenSC and added it as PKCS#11 library to VeraCrypt. Importing the keyfile to VeraCrypt works as described, and I can see it as PrivDO1 with the token OpenPGP card (User PIN).

HOWEVER, there is a massive security issue! The keyfile is not protected by the PIN that I set for the card. It can be read without any authentication using e.g. openpgp-tool from OpenSC:

openpgp-tool.exe -d 1
Using reader with a card: Nitrokey CCID/ICCD Interface 0
69 D6 4D 55 6D BC 87 65 AF 26 55 99 31 39 A9 92 i.MUm..e.&U.19..
66 75 23 C1 CD 7E 60 15 42 4A 60 3A 22 9E 5A E1 fu#..~`.BJ`:".Z.
C0 EC 85 DF C3 EF A0 01 6B A9 46 F4 DC 96 63 9C ........k.F...c.
E7 31 44 B0 ED 2D 1D 87 D9 F9 11 5A 52 6B F8 6D .1D..-.....ZRk.m

… or gpg --edit-card:

gpg --edit-card

Reader ...........: Nitrokey CCID/ICCD Interface 0
Application ID ...: D276000124010304000FE16B14F70000
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Nitrokey
Serial number ....: [redacted]
Name of cardholder: [redacted]
Language prefs ...: [nicht gesetzt]
Salutation .......:
URL of public key : [nicht gesetzt]
Login data .......: [nicht gesetzt]
Private DO 1 .....: i\xd6\x4dUm\xbc\x87e\xaf&U\x9919\xa9\x92fu#\xc1\xcd~`\x15BJ`:"\x9eZ\xe1\xc0\xec\x85\xdf\xc3\xef\xa0\x01k\xa9F\xf4\xdc\x96c\x9c\xe7\x31D\xb0\xed\x2d\x1d\x87\xd9\xf9\x11ZRk\xf8\x6d

This obviously defeats the purpose of putting the keyfile on the Nitrokey. Note that I unplugged the Nitrokey to clear any cached PINs.

Please advise how to secure the VeraCrypt keyfile on the Nitrokey with the PIN (or don’t advertise this feature in your documentation).

1 Like

After a bit of research: Private Data Object 01 is indeed supposed to be always readable, according to the OpenPGP card spec 3.4.

So, how do I get VeraCrypt / the Nitrokey to use PrivDO3 instead?

Imho, at the very least the documentation on the Nitrokey site should be removed or reworked, since having a key file always accessible defeats the purpose of putting it on the NK3 in the first place.

Hello, in the documentation it clearly state that this is not safe and Aloaha Crypt is recommended which do not have this problem.

I’m sorry, but the documentation does not state that the key files are completely unprotected. In fact it incorrectly states quite the opposite:

Instead it stores a keyfile on the Nitrokey which theoretically could be stolen by a computer virus after the user enters the PIN.

There is no PIN input required!

1 Like

You are right sorry, the PR is on its way.

Concerning changing the slot there is a github issue open on Verascrypt repo here:

I did some debugging by capturing OpenSC’s debug output, while storing a keyfile on the Nitrokey with VeraCrypt. The relevant snippet is:

P:24016; T:17652 2026-02-12 22:07:46.329 [opensc-pkcs11] pkcs15-lib.c:2261:sc_pkcs15init_store_data_object: called
P:24016; T:17652 2026-02-12 22:07:46.329 [opensc-pkcs11] pkcs15-lib.c:2416:sc_pkcs15init_store_data: called
P:24016; T:17652 2026-02-12 22:07:46.329 [opensc-pkcs11] pkcs15-openpgp.c:433:openpgp_store_data: called
P:24016; T:17652 2026-02-12 22:07:46.329 [opensc-pkcs11] ===== App label test.bin
P:24016; T:17652 2026-02-12 22:07:46.329 [opensc-pkcs11] About to write to DO 0101
P:24016; T:17652 2026-02-12 22:07:46.329 [opensc-pkcs11] called; type=2, path=0101
P:24016; T:17652 2026-02-12 22:07:46.329 [opensc-pkcs11] card-openpgp.c:1459:pgp_select_file: called
P:24016; T:17652 2026-02-12 22:07:46.329 [opensc-pkcs11] called, tag=0101

This points towards the openpgp_store_data function in OpenSC, which has the following comment: “Currently, we only support DO 0101.”

This explains why the keyfile is always stored as Private Data Object PrivDO1 by VeraCrypt, which – again – does defeat the purpose of putting the keyfile on the Nitrokey in the first place.

Thank you for starting the PR regarding the documentation.

So, I’ve been writing my own PKCS#11 library from scratch that exposes the PIN-protected PrivDO3 to VeraCrypt to use as key file. It’s working now:

… though perhaps lacking some error handling and documentation. Depending on my spare time and public interest, I might polish it for future release.

1 Like

Here is my PKCS11 library that allows VeraCrypt to use the PIN-protected PrivDO3 on the Nitrokey:

I’ve been using it daily for about a week, without encountering issues. But please note that it is provided “as is”, according to its license terms.