GNUK на BluePill 2
Пишем OpenPGP ключ на криптографический токен.
/| .----. |\
/ | __ | | __ | \
| .Y` `\| |/` `Y. |
| | `--` | |
\| ,----, |/
| / \ |
| | | |
| / ) GNUK ( \ |
\/ /| |\ \/
| | \ / | |
| |\ ~----~ /| |
| | ~-.______.-~ | |
| \ ___ ____/ |
\ ~~~~ /
~ - .____. - ~
Заметка: Команды выполнены на реальном оборудовании, результат может отличаться от вашего.
В работе экосистемы смарт-карт задействовано много демонов и служб. Убедитесь, что у вас установлены и запущены все из них:
+-----+
| gpg | <-+
+-----+ |
|
+-----+ | +-----------+ +----------+ +-------+ +---------+ +-----+
| ssh | <-+-> | gpg_agent | <-> | scdaemon | <-> | pcscd | <-> | libccid | <-> | USB |
+-----+ | +-----------+ +----------+ +-------+ +---------+ +-----+
|
+---------+ +-------+ |
| mozilla | <-> | scute | <-+
+---------+ +-------+
Начальная настройка
Gnuk не позволяет устанавливать пароли до импорта приватных ключей, поэтому произведём начальную настройку.
Переходим в интерактивный режим настройки токена GPG:
$ gpg --card-edit
Reader ...........: 234B:0000:FSIJ-2.2-4314351B:0
Application ID ...: D276000124010200FFFE4314351B0000
Application type .: OpenPGP
Version ..........: 2.0
Manufacturer .....: unmanaged S/N range
Serial number ....: 4314351B
Name of cardholder: [not set]
Language prefs ...: [not set]
Salutation .......:
URL of public key : [not set]
Login data .......: [not set]
Signature PIN ....: forced
Key attributes ...: ed25519 cv25519 ed25519
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
KDF setting ......: off
UIF setting ......: Sign=off Decrypt=off Auth=off
Signature key ....: [none]
Encryption key....: [none]
Authentication key: [none]
General key info..: [none]
Разрешаем команды администратора:
gpg/card> admin
Admin commands are allowed
Настраиваем KDF-DO (Key Derived Function - Data Object) (функция OpenPGP, позволяющая безопасно генерировать приватные ключи с использованием ресурсов хоста):
gpg/card> kdf-setup
Бонус: Настраиваем KDF-DO на использование одного кода (adminless):
gpg/card> kdf-setup single
Здесь нужен PIN-код администратора. Стандартно установлены следующие:
User: 123456
Admin: 12345678
Опционально: Добавляем имя, логин, язык, пол, приветствие и URL публичного ключа соответственно:
gpg/card> name
Cardholder's surname: Savin
Cardholder's given name: Aleksei
gpg/card> login
Login data (account name): lessavin
gpg/card> lang
Language preferences: ru
gpg/card> sex
Salutation (M = Mr., F = Ms., or space): M
gpg/card> salutation
Salutation (M = Mr., F = Ms., or space): M
gpg/card> url
URL to retrieve public key: https://lessavin.ru/6D3554C2128F2DB5C783D74CB6C5D439AF2E62B5.asc
Опционально: Отключаем PIN-код для цифровой подписи.
gpg/card> forcesig
Выходим из интерактивного режима:
gpg/card> quit
Генерация ключей
Gnuk на данный момент (версия 2.2) поддерживает алгоритмы Ed25519 и X25519, а также экспериментально Ed448 и X448. Для генерации пары ключей изучите мою предыдущую статью про GnuPG.
Внимание: После генерации ключей на компьютере сохраните приватный ключ в надёжном месте. Для безопасности в токене отсутствует функция экспорта ключей.
Импорт ключей
Переходим в интерактивного режима GPG ключа:
$ gpg --edit-key 6D3554C2128F2DB5C783D74CB6C5D439AF2E62B5
gpg (GnuPG) 2.4.7; Copyright (C) 2024 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Secret key is available.
sec ed25519/B6C5D439AF2E62B5
created: 2026-07-16 expires: 2029-07-16 usage: SC
trust: ultimate validity: ultimate
ssb cv25519/64446374763F07DC
created: 2026-07-16 expires: 2029-07-16 usage: E
ssb ed25519/03B7C091952C3E12
created: 2026-07-16 expires: 2029-07-15 usage: A
[ultimate] (1). Aleksei Savin <lessavin@hotmail.com>
Импортируем основной ключ:
gpg> keytocard
Really move the primary key? (y/N) y
Please select where to store the key:
(1) Signature key
(3) Authentication key
Your selection? 1
sec ed25519/B6C5D439AF2E62B5
created: 2026-07-16 expires: 2029-07-16 usage: SC
trust: ultimate validity: ultimate
ssb cv25519/64446374763F07DC
created: 2026-07-16 expires: 2029-07-16 usage: E
ssb ed25519/03B7C091952C3E12
created: 2026-07-16 expires: 2029-07-15 usage: A
[ultimate] (1). Aleksei Savin <lessavin@hotmail.com>
Note: the local copy of the secret key will only be deleted with "save".
Выделяем подключ 1:
gpg> key 1
sec ed25519/B6C5D439AF2E62B5
created: 2026-07-16 expires: 2029-07-16 usage: SC
trust: ultimate validity: ultimate
ssb* cv25519/64446374763F07DC
created: 2026-07-16 expires: 2029-07-16 usage: E
ssb ed25519/03B7C091952C3E12
created: 2026-07-16 expires: 2029-07-15 usage: A
[ultimate] (1). Aleksei Savin <lessavin@hotmail.com>
Импортируем подключ 1:
gpg> keytocard
Please select where to store the key:
(2) Encryption key
Your selection? 2
sec ed25519/B6C5D439AF2E62B5
created: 2026-07-16 expires: 2029-07-16 usage: SC
trust: ultimate validity: ultimate
ssb* cv25519/64446374763F07DC
created: 2026-07-16 expires: 2029-07-16 usage: E
ssb ed25519/03B7C091952C3E12
created: 2026-07-16 expires: 2029-07-15 usage: A
[ultimate] (1). Aleksei Savin <lessavin@hotmail.com>
Note: the local copy of the secret key will only be deleted with "save".
Снимаем выделение с подключа 1:
gpg> key
sec ed25519/B6C5D439AF2E62B5
created: 2026-07-16 expires: 2029-07-16 usage: SC
trust: ultimate validity: ultimate
ssb cv25519/64446374763F07DC
created: 2026-07-16 expires: 2029-07-16 usage: E
ssb ed25519/03B7C091952C3E12
created: 2026-07-16 expires: 2029-07-15 usage: A
[ultimate] (1). Aleksei Savin <lessavin@hotmail.com>
Выделяем подключ 2:
gpg> key 2
sec ed25519/B6C5D439AF2E62B5
created: 2026-07-16 expires: 2029-07-16 usage: SC
trust: ultimate validity: ultimate
ssb cv25519/64446374763F07DC
created: 2026-07-16 expires: 2029-07-16 usage: E
ssb* ed25519/03B7C091952C3E12
created: 2026-07-16 expires: 2029-07-15 usage: A
[ultimate] (1). Aleksei Savin <lessavin@hotmail.com>
Импортируем подключ 2:
gpg> keytocard
Please select where to store the key:
(3) Authentication key
Your selection? 3
sec ed25519/B6C5D439AF2E62B5
created: 2026-07-16 expires: 2029-07-16 usage: SC
trust: ultimate validity: ultimate
ssb cv25519/64446374763F07DC
created: 2026-07-16 expires: 2029-07-16 usage: E
ssb* ed25519/03B7C091952C3E12
created: 2026-07-16 expires: 2029-07-15 usage: A
[ultimate] (1). Aleksei Savin <lessavin@hotmail.com>
Note: the local copy of the secret key will only be deleted with "save".
Сохраняем результат и выходим:
gpg> save
$
Бонус: Загружаем ключи, не удаляя с компьютера (вместо последнего шага):
gpg> quit
Save changes? (y/N) n
Quit without saving? (y/N) y
$
Смена PIN-кодов
Теперь, когда ключи были перенесены на токен, можно сменить PIN-коды.
Переходим в интерактивного режима GPG токена:
$ gpg --card-edit
Reader ...........: 234B:0000:FSIJ-2.2-4314351B:0
Application ID ...: D276000124010200FFFE4314351B0000
Application type .: OpenPGP
Version ..........: 2.0
Manufacturer .....: unmanaged S/N range
Serial number ....: 4314351B
Name of cardholder: Aleksei Savin
Language prefs ...: ru
Salutation .......: Mr.
URL of public key : https://lessavin.ru/6D3554C2128F2DB5C783D74CB6C5D439AF2E62B5.asc
Login data .......: lessavin
Signature PIN ....: not forced
Key attributes ...: ed25519 cv25519 ed25519
Max. PIN lengths .: 127 127 127
PIN retry counter : 3 3 3
Signature counter : 0
KDF setting ......: on
UIF setting ......: Sign=off Decrypt=off Auth=off
Signature key ....: 6D35 54C2 128F 2DB5 C783 D74C B6C5 D439 AF2E 62B5
created ....: 2026-07-16 09:14:36
Encryption key....: 5E48 B653 64DF F9CD A282 62D9 6444 6374 763F 07DC
created ....: 2026-07-16 09:14:36
Authentication key: D521 62B0 0A26 A4F6 9C75 1248 03B7 C091 952C 3E12
created ....: 2026-07-16 09:16:06
General key info..:
pub ed25519/B6C5D439AF2E62B5 2026-07-16 Aleksei Savin <lessavin@hotmail.com>
sec> ed25519/B6C5D439AF2E62B5 created: 2026-07-16 expires: 2029-07-16
card-no: FFFE 4314351B
ssb> cv25519/64446374763F07DC created: 2026-07-16 expires: 2029-07-16
card-no: FFFE 4314351B
ssb> ed25519/03B7C091952C3E12 created: 2026-07-16 expires: 2029-07-15
card-no: FFFE 4314351B
Разрешаем команды администратора:
gpg/card> admin
Admin commands are allowed
Меняем PIN-код администратора:
gpg/card> passwd
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Your selection? 3
PIN changed.
Меняем PIN-код пользователя:
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Your selection? 1
PIN changed.
Опционально Задаем PIN-код сброса.
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Your selection? 4
Reset Code set.
Выходим из меню:
1 - change PIN
2 - unblock PIN
3 - change Admin PIN
4 - set the Reset Code
Q - quit
Your selection? Q
Выходим из интерактивного режима:
gpg/card> quit
Поздравляю, вы успешно настроили токен. В следующей статье мы разберём способы применения токена.
P.S. Для наглядности был выбран GPG, но в качестве более удобной альтернативы рекомендую использовать Kleopatra, графический интерфейс для GnuPG.