Nitrokey 3
goals:
- Initial device setup
- OpenPGP card setup
- PIV setup
- FIDO setup
- KeepassXC integration
udev rules
udev is a device manager for the Linux kernel that dynamically manages and creates device nodes in the /dev directory.
# fetch rules
$ curl -OL https://raw.githubusercontent.com/Nitrokey/nitrokey-udev-rules/main/41-nitrokey.rules
# move rules to udev rules
> mv 41-nitrokey.rules /etc/udev/rules.d/
# change permissions
> chown root:root /etc/udev/rules.d/41-nitrokey.rules
> chmod 644 /etc/udev/rules.d/41-nitrokey.rules
# reload rules and trigger event manually
> udevadm control --reload-rules \
&& udevadm trigger
nitropy setup
nitropy is a command-line interface for the Nitrokey FIDO2, Nitrokey Start, Nitrokey 3, Nitrokey Passkey and NetHSM
# install python pipx
> pacman -S python-pipx
# install nitropy
$ pipx ensurepath \
&& pipx install pynitrokey
# will be stored in "$HOME/.local/bin/nitropy"
# example command are:
$ nitropy nk3 'list|update|factory-reset'
update and reset
after updating the device a reset was neccessary on my side to get it finally running
# update device
$ nitropy nk3 factory-reset
# reset after update
$ nitropy nk3 factory-reset
gpg setup
official documentation:
# disables the built-in CCID driver of GnuPG's scdaemon
disable-ccid
# cache passphrase for 300 seconds
default-cache-ttl 300
# maximum time how long the passphrase can be cached at all
max-cache-ttl 7200
# check card status
$ gpg2 -vvv --card-status
...
gpg: enabled compatibility flags:
gpg: selecting card failed: No such device
gpg: OpenPGP card not available: No such device
# kill agent if the cmd prints error
$ pkill gpg-agent
# try it again
$ gpg2 -vvv --card-status
...
Reader ...........: Nitrokey Nitrokey 3 [CCID/ICCD Interface] 00 00
Application ID ...: XXXXXXXXXXXXXXXXXXXXXXXX
Application type .: OpenPGP
Version ..........: 3.4
Manufacturer .....: Nitrokey
set pins
official documentation:
# set/change fido pin
$ nitropy fido2 set-pin
$ nitropy fido2 change-pin
# set/change secrets pin
$ nitropy nk3 secrets set-pin
$ nitropy nk3 secrets change-pin
# set openpgp card user pin (default is: 123456)
$ gpg --card-edit
passwd
# set openpgp card admin pin (default is: 12345678)
$ gpg --card-edit
admin
passwd
3
# change piv (default is: 123456), requires pkg: 'pivy'
$ pivy-tool change-pin
# change puk (default is: 123456), requires pkg: 'pivy'
$ pivy-tool change-puk
set algorithms
RSA-2048
RSA-3072 (no key generation, key import only)
RSA-4096 (no key generation, key import only)
EcDSA and ECDH for P256
EdDSA and ECDH for Curve25519
setup Edward 25519
# check current algorithm
$ gpg --card-status | grep Key\ attributes
...
Key attributes ...: rsa2048 rsa2048 rsa2048
# open card
$ gpg2 --card-edit
gpg/card> admin
...
Admin commands are allowed
# change attributes
gpg/card> key-attr
Changing card key attribute for: Signature key
Please select what kind of key you want:
(1) RSA
(2) ECC
Your selection? 2
Please select which elliptic curve you want:
(1) Curve 25519 *default*
(4) NIST P-384
(6) Brainpool P-256
Your selection? 1
The card will now be re-configured to generate a key of type: ed25519
Note: There is no guarantee that the card supports the requested
key type or size. If the key generation does not succeed,
please check the documentation of your card to see which
key types and sizes are supported.
Changing card key attribute for: Encryption key
Please select what kind of key you want:
(1) RSA
(2) ECC
Your selection? 2
Please select which elliptic curve you want:
(1) Curve 25519 *default*
(4) NIST P-384
(6) Brainpool P-256
Your selection? 1
The card will now be re-configured to generate a key of type: cv25519
Changing card key attribute for: Authentication key
Please select what kind of key you want:
(1) RSA
(2) ECC
Your selection? 2
Please select which elliptic curve you want:
(1) Curve 25519 *default*
(4) NIST P-384
(6) Brainpool P-256
Your selection? 1
The card will now be re-configured to generate a key of type: ed25519
# leave card and check status again
> gpg --card-status | grep Key\ attributes
...
Key attributes ...: ed25519 cv25519 ed25519
create keys
Generate GPG keys on device:
# open card editor
> gpg2 --card-edit
# change to admin
gpg/card> admin
...
Admin commands are allowed
# create keys
gpg/card> generate
# no off-card backups
Make off-card backup of encryption key? (Y/n) n
# key dont expire
Key is valid for? (0)
# add details
Real name: Jane Doe
Email address: jane@example.com
Comment: jdoe
You selected this USER-ID:
"Jane Doe (jdoe) <jane@example.com>"
# confirm data
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
# expected output
public and secret key created and signed.
add aliases
To add more email addresses we use the adduid
function while the device is plugged-in.
# list all private keys and pick your target key_id
> gpg --list-secret-keys --keyid-format=long
# edit the target key
> gpg --edit-key XXXXXXXXXXXX
# add aliases
gpg> adduid
# add name, email address and comments
Real name: Jane Doe
Email address: jane2@example.com
Comment: jdoe2
You selected this USER-ID:
"Jane Doe (jdoe2) <jane2@example.com>"
# confirm data
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
# system will ask for device pin
# save key
gpg> save
piv setup
# install pivy-tool to "/opt/pivy/bin/"
$ git clone https://github.com/arekinath/pivy
$ cd pivy; make
> make install
piv reset
# reset PIV smartcard if nothing works like on my side
# the rest of the device will stay untouched
$ opensc-tool \
-s 00:A4:04:00:0B:A000000308000010000100 \
-s 00:20:00:80:08:FFFFFFFFFFFFFFFF \
-s 00:20:00:80:08:FFFFFFFFFFFFFFFF \
-s 00:20:00:80:08:FFFFFFFFFFFFFFFF \
-s 00:FB:00:00
# setup after reset
$ pivy-tool setup
# get smartcard info
$ pivy-tool list
piv ssh
# fetch public key from PIV smartcard
$ pivy-tool -a eccp256 generate 9A
$ pkcs15-tool --read-ssh-key 1
# connect to server using pkcs#11
$ ssh example.org -I /usr/lib64/opensc-pkcs11.so
# use pivy-agent to benefit from ssh-agent
# pivy-agent -g <your_guid> <your_shell>
> pivy-agent -g XXXXXXXXXXX zsh
# enter piv pin to unlock agent
> ssh-add -X
# check ssh-agent in sub-shell
> ssh-add -l
see: https://github.com/arekinath/pivy
fido2
FIDO2 is a modern, two-factor authentication standard that enables passwordless login, providing a higher level of security through public key cryptography by authenticating users with hardware devices or biometric verification
fido ssh
# create a resident key, saved on the token instead
$ ssh-keygen -t ed25519-sk \
-O resident \
-O verify-required \
-C "FIDO Token"
# list key on device
> nitropy fido2 list-credentials
# on server side, you could add to "/etc/ssh/sshd_config"
PubkeyAuthOptions verify-required
fido luks setup
# install fido library
> pacman -S libfido2
# refresh initramfs
> mkinitcpio -P
# list devices
$ systemd-cryptenroll --fido2-device=list
# list keyslots
> systemd-cryptenroll /dev/nvme0n1p2
# enroll fido on encrypted device
> systemd-cryptenroll \
--fido2-device=auto \
--fido2-with-client-pin=true \
--fido2-with-user-presence=true \
--fido2-credential-algorithm=eddsa \
/dev/nvme0n1p2
# modify systemd-boot config
# - rd.luks.options=fido2-device=auto
> edit /boot/loader/entries/arch.conf
...
options rd.luks.options=fido2-device=auto ...
# update bootloader
> bootctl update
# add hooks to initramfs
# - systemd
# - sd-vconsole
# - sd-encrypt
> edit /etc/mkinitcpio.conf
...
# before
HOOKS=(base udev autodetect modconf block keyboard keymap encrypt lvm2 filesystems fsck shutdown)
# after
HOOKS=(base udev systemd autodetect modconf block keyboard sd-vconsole keymap encrypt lvm2 sd-encrypt filesystems fsck shutdown)
# refresh initramfs
> mkinitcpio -P
# reboot and test
see arch wiki
keepassxc
# create a 20 bytes length key
$ dd if=/dev/urandom of=/tmp/nk3 bs=20 count=1
# add key to device' slot 1 or 2
$ nitropy nk3 secrets add-challenge-response 1 $(base32 /tmp/nk3)
# repeat adding the key to all backup devices as well
# remove key locally
$ shred /tmp/nk3
$ rm /tmp/nk3
create a database backup first
In KeepassXC go to:
Database > Database Security
Click on:
add Challange-Response
Test all devices before clicking on OK.
Ensure that a password is set if you need one, same for an eventual keyfile
Click OK
alternative way
See this linux-bibel.at post as well if you like hold it more handy.
# generate a passphrase and encrypt it using nk3
$ keepassxc-cli generate --length 64 -l -U -n | \
gpg --encrypt --recipient <your_keyID> --output ~/keepassxc-pw_encrypted.gpg
# use the passphrase to create a KeepassXC database
$ printf "`gpg --quiet --decrypt ~/keepassxc-pw_encrypted.gpg`\n`gpg --quiet --decrypt ~/keepassxc-pw_encrypted.gpg`" | \
keepassxc-cli db-create -p ~/keepassxc-datenbank.kdbx 2> /dev/null
# run KeepassXC while reading the decrypted secret from stdin
$ gpg --decrypt ~/keepassxc-pw_encrypted.gpg | \
keepassxc ~/keepassxc-datenbank.kdbx --pw-stdin
general handling
# removing gpg keys locally after unplugging device
$ gpg --delete-secret-and-public-key XXXXXX
# extract ssh key
$ gpg2 --export-ssh-key XXXXXX > ~/.ssh/id_nk3.pub
# remove challange-response from device
$ nitropy nk3 secrets list
$ nitropy nk3 secrets remove HmacSlot1
# remove fido from luks
> systemd-cryptenroll \
--wipe-slot=fido2 \
/dev/nvme0n1p2
links
Great blog about: https://dokuwiki.nausch.org/doku.php/nitrokey:linuxmint:3cnfc