Export-ssh-key operation fails ssh login fails

I try to use

Nitrokey pro
NitrokeyApp 1.4.0
Firmware 0.11
Karten-Seriennummer 81a3

for ssh server login from Windows (putty) to FreeBSD. I have tried to apply the gpg-connect-agent for this purpose. On Startup “gpg-connect-agent.exe /bye” is run. I see a console windwow popping up. However, putty still asks for normal password login. As public key I tried to use

gpg --armor --export name@domain.de > authorized_keys

This file - it seem to be a GPG key - is written. But I need an SSH key.
However, this won’t work. The export fails:

gpg --export-ssh-key name@domain.de > authorized_keys

gpg: Schlüssel "name@domain.de" nicht gefunden: Mehrdeutiger Name
gpg: Schlüsselexport im SSH Format fehlgeschlagen: Mehrdeutiger Name

Why does this fail. Does the key file in the first case have the wrong format
and may this be the reason why the key login fails?

I wonder also why I’m not prompted for a password to unlock the Nitrokey.

Card status looks like (some data rendered anonymous):

gpg --card-status

Reader ...........: Nitrokey Nitrokey Pro 0
Application ID ...: D2760001240103030005000081A30000
Application type .: OpenPGP
Version ..........: 3.3
Manufacturer .....: ZeitControl
Serial number ....: 000081A3
Name of cardholder: [nicht gesetzt]
Language prefs ...: de
Salutation .......:
URL of public key : [nicht gesetzt]
Login data .......: [nicht gesetzt]
Signature PIN ....: zwingend
Key attributes ...: rsa4096 rsa4096 rsa4096
Max. PIN lengths .: 64 64 64
PIN retry counter : 3 0 3
Signature counter : 4
KDF setting ......: off
Signature key ....: XXXX XXXX XXXX XXXX XXXX  XXXX XXXX XXXX XXXX XXXX
      created ....: 2020-06-06 14:56:16
Encryption key....: XXXX XXXX XXXX XXXX XXXX  XXXX XXXX XXXX XXXX XXXX
      created ....: 2020-06-06 14:56:16
Authentication key: XXXX XXXX XXXX XXXX XXXX  XXXX XXXX XXXX XXXX XXXX
      created ....: 2020-06-06 14:56:16
General key info..: pub  rsa4096/SSSSSSSSSSSSSSSS 2020-06-06 Joe Miller <name@domain.de>
sec>  rsa4096/SSSSSSSSSSSSSSSS  erzeugt: 2020-06-06  verfällt: niemals
                                Kartennummer:0005 000081A3
ssb>  rsa4096/YYYYYYYYYYYYYYYY  erzeugt: 2020-06-06  verfällt: niemals
                                Kartennummer:0005 000081A3
ssb>  rsa4096/ZZZZZZZZZZZZZZZZ  erzeugt: 2020-06-06  verfällt: niemals
                                Kartennummer:0005 000081A3

I used this method for key creation (gpg instead of gpg2 on Windows):

https://www.nitrokey.com/documentation/openpgp-create-on-device

Then I try to login with this method:

https://www.nitrokey.com/de/documentation/applications#os:windows&a:ssh-for-server-administration

PGP public key is placed in ~/.ssh/authorized_keys

You have two keys for the same mail address, therefore it is not clear which one to choose. You should use SSSSSSSSSSSSSSSS (fingerprint of the pub key) instead of the mail. This way the export should work.

The PIN is only needed/used if private data on the Nitrokey is accessed. The public key is not such data.

Thank you very much nitroalex! Actually

gpg --export-ssh-key SSSSSSSSSSSSSSSS > authorized_keys

works. :slight_smile:

“gpg --card-status”, however, does not give any hint to me that there are 2 “keys”. (Actually, a “key” seems to be a set of keys.) “gpg --list-keys” which queries the disk instead of the stick shows 2 “key sets” with the same identity.

I made a mistake when I first created rsa2048 keys directly on the Nitrokey and then switched the key to rsa4096. After this, “card-status” no longer showed any keys. I then created rsa4096 keys. At least remains of the rsa2048 keys survived perhaps only on disk.

The following questions arise:

  • Is the rsa2048 “key set” still on the key? How can I see this?
  • Did the rsa2048 “key set” entries only survive on disk and now point to nothing?

Glad it worked. Using --card-status only shows the results for the keys on the card. The keys you see with --list-keys shows all keys in the GnuPG keyring. The keyring stores so called “key stubs”. This means, the actual secret key is stored on the Nitrokey, GnuPG just stores a stub which points to the card. If you are erasing the keys on the Nitrokey, GnuPG does not know delete the key stubs.

This is the reason why you had two key sets with the same identity on your keyring while the actual keys was already delete on your Nitrokey.

I hope this explanation is not more confusing, but helping :slight_smile:

Thank you again nitroalex! This confirms my guesses. I removed the superfluous key remains on my SSD by

gpg --delete-secret-key fingerprint_of_rsa2048_key
gpg --delete-key fingerprint_of_rsa2048_key

Now gpg only stores a single rsa4096 key collection. After this action, this works:

 gpg --export-ssh-key name@domain.de > ssl.key

For other readers I partially explain the output of “gpg --card-status”:

                    <------------ fingerprint ------------->
                                            <--- longID --->
Signature key ....: ssssssssssssssssssssssssSSSSSSSSSSSSSSSS
      created ....: 2020-06-06 14:56:16
Encryption key....: eeeeeeeeeeeeeeeeeeeeeeeeEEEEEEEEEEEEEEEE
      created ....: 2020-06-06 14:56:16
Authentication key: aaaaaaaaaaaaaaaaaaaaaaaaAAAAAAAAAAAAAAAA
      created ....: 2020-06-06 14:56:16
General key info..: pub  rsa4096/SSSSSSSSSSSSSSSS 2020-06-06 My Name <name@domain.de>
sec>  rsa4096/SSSSSSSSSSSSSSSS  erzeugt: 2020-06-06  verfällt: niemals
                                Kartennummer:0005 000081A3
ssb>  rsa4096/AAAAAAAAAAAAAAAA  erzeugt: 2020-06-06  verfällt: niemals
                                Kartennummer:0005 000081A3
ssb>  rsa4096/EEEEEEEEEEEEEEEE  erzeugt: 2020-06-06  verfällt: niemals
                                Kartennummer:0005 000081A3
  • Fingerprint: 160 bits long, 40 hex ASCII characters (blanks removed!)
  • long ID: the last 64 bits of the fingerprint, 16 hex ASCII characters
  • short ID: the last 32 bits of the fingerprint, 8 hex ASCII characters
  • pub: PUBlic key
  • sec: SECret key
  • ssb: Secret SuBkey
  • Signature key <-> pub <-> sec
  • Encryption key <-> ssb (last line!)
  • Authentication <-> ssb (middle line!)

So it appears to be that there are 3 private keys stored on the Nitrokey.

I learned that a key is actually a key collection and what GnuPG calls a “public key” is just the oldest signing key in the collection. However, for mathematical reasons this cannot be the public key applicable to each of the three secret keys. I, furthermore, experienced that no matter what keyId I enter

gpg --export-ssh-key SSSSSSSSSSSSSSSS > ssh1.key
gpg --export-ssh-key AAAAAAAAAAAAAAAA > ssh2.key
gpg --export-ssh-key EEEEEEEEEEEEEEEE > ssh3.key
gpg --armor --export SSSSSSSSSSSSSSSS > pgp1.asc
gpg --armor --export AAAAAAAAAAAAAAAA > pgp2.asc
gpg --armor --export EEEEEEEEEEEEEEEE > pgp3.asc

I always get the same (1 == 2 == 3) key. This is confusing.

gpg --export-ssh-key AAAAAAAAAAAAAAAA > ssh.key

should export the “public key” of A… (auth) and not of S… (sign).

Perhaps “export-ssh-key” exports indeed the A pubkey, while “export” saves the S pubkey? For sure these options control the export format. What is unclear to me is whether the same public key is exported just in a different format. And if so, it seems strange that this pubkey (the oldest signing key) works with the secret A key.

Key-based SSL authentication with putty works even though I don’t understand why.

Note: After wakeup from sleep state, the nitrokey has to be removed and plugged in again. Otherwise, the key-based SSL authentication won’t work.

export-ssh-key will always export the pubkey of slot 3 as this is the only one that can be used for ssh via gpg-agent and this subkey needs to be A (authentication) anyway.

A simple “export” will only export the public key (GnuPG ID) which is always connected to the C (certify) key (but it will contain information about all subkeys as well, of course).

A --export-secret-keys will export everything afaik.

Thank you once more, nitroalex! This confirms my guesses.