
Безопасная эксплуатация ноутбуков, или Защита пользовательского ключа с помощью алгоритмов ГОСТ Р 34.10-2012
В третьей части мы настроили защиту мастер-ключа с помощью USB-токена, используя RSA, но теперь мы перейдем на алгоритмы ГОСТ Р 34.10-2012. Жаркие. Зимние. Твои. А еще они основаны на более перспективных эллиптических кривых, которым не нужны такие большие ключи, чтобы обеспечить более высокий уровень безопасности.
Схема работы с USB-токенами и необходимые компоненты
Государственный стандарт Р 34.10-2012 предусматривает работу с открытыми и закрытыми ключами, но поддерживает только создание и проверку цифровых подписей без возможности шифровать данные на асимметричных ключах. Вместе с тем, для безопасного обмена сообщениями между клиентом и сервером на ключах ГОСТ Р 34.10-2012 можно выработать общий ключ симметричного шифрования по схеме, которая отражена на рисунке 10.

Механизм выработки общего ключа работает на основе алгоритма Диффи-Хеллмана (в PKCS#11 константа, обозначающая этот механизм, называется CKM_GOSTR3410_2012_DERIVE), схема работы показана на рисунке 11. Эту же схему можно применить и для формирования ключа, с помощью которого шифровать мастер-ключ LUKS.

Далее общий ключ симметричного шифрования, полученный на основе ключей ГОСТ Р 34.10-2012, можно использовать для шифрования пользовательского ключа LUKS, как мы это делали в случае RSA (способ 1), или сразу в качестве пользовательского ключа LUKS для шифрования непосредственно мастер-ключа зашифрованного диска (способ 2).

Как известно, нет ничего хуже, чем изобретать велосипед, тем более, когда этот велосипед должен ездить на принципах криптографии. Коллеги из Selectel в прошлом году довольно основательно проехались по этой теме в своей статье Зашифруй или проиграешь. Мы тоже придерживаемся такого мнения, поэтому внимательно ознакомились с кодом упомянутой ранее службы systemd-cryptenroll и предлагаем использовать общий ключ симметричного шифрования непосредственно как пользовательский ключ LUKS, что существенно упростит схему работы (способ 2).

Для работы с отечественной криптографией из Linux можно обращаться к модулю librtpkcs11ecp.so напрямую (на Python это можно делать, например, с использованием ctypes) или вызывать утилиту openssl с использованием модулей расширения (интеграции) rtengine. С помощью модулей интеграции через стандартный интерфейс OpenSSL можно решать следующие задачи:
электронная подпись по ГОСТ Р 34-10.2001, ГОСТ Р 34-10.2012, RSA, ECDSA;
вычисление хеш-функции по ГОСТ Р 34-11.94, ГОСТ Р 34-11.2012;
симметричное шифрование и вычисление имитовставки по ГОСТ 28147-89;
распределение ключей по схеме VKO 34.10-2001 и VKO 34.10-2012;
электронная подпись и шифрование PKCS#7, CMS, S/MIME;
формирование запросов на сертификаты PKCS#10;
работа с сертификатами X.509 и списками отзыва(CRL);
клиентская часть протокола TLS-ГОСТ;
онлайн-проверка статуса сертификата (OCSP);
работа с временными метками (TSP).
Установка и настройка пакетов
Если вы еще не читали третью часть статьи, то выполните дополнительно следующие команды, чтобы установить компоненты, необходимые для работы с USB-токенами:
sudo apt install --yes pcscd opensc jq wget https://download.rutoken.ru/Rutoken/PKCS11Lib/2.18.1.0/Linux/x64/librtpkcs11ecp\_2.18.1.0-1\_amd64.deb md5sum librtpkcs11ecp_2.18.1.0-1_amd64.deb | grep 9482c068baca79b3070c1f1f8d7605d3 if [ $? -eq 0 ]; then sudo dpkg -i librtpkcs11ecp_2.18.1.0-1_amd64.deb fi wget https://download.rutoken.ru/Rutoken/Utilites/rtAdmin/3.1/Linux/glibc-x86_64/rtadmin md5sum rtadmin | grep 677712b1fe211b74ff3391b927114f73 if [ $? -eq 0 ]; then chmod +x rtadmin sudo cp rtadmin /usr/bin/ fi
Как мы уже говорили, библиотека openssl не поддерживает работу с отечественными алгоритмами, но такую поддержку можно добавить с помощью внешнего модуля rtengine от компании «Актив». Скачаем этот модуль с официального сайта с помощью утилиты wget:
wget https://download.rutoken.ru/Rutoken/Support_OpenSSL/Current/rtengine-1.6.2.zip
Проверим контрольную сумму и распакуем файлы в папку /usr/lib:
md5sum rtengine-1.6.2.zip | grep 50624947e25e91c4dc9dd983fb1a46b6 if [ $? -eq 0 ]; then sudo unzip rtengine-1.6.2.zip -d /usr/lib/ fi
В конфигурационном файле /usr/lib/ssl/openssl.cnf потребуется установить значение параметра «openssl_conf = openssl_def» и добавить в конец строки для настройки модуля rtengine:
Файл /usr/lib/ssl/openssl.cnf
#openssl_conf = default_conf openssl_conf = openssl_def ... [openssl_def] engines = engine_section [engine_section] rtengine = gost_section [gost_section] dynamic_path = /usr/lib/rtengine/1.6.2/Linux/x64/lib/librtengine.so pkcs11_path = /usr/lib/librtpkcs11ecp.so rand_token = pkcs11:manufacturer=Aktiv%20Co.;model=Rutoken%20ECP default_algorithms = CIPHERS, DIGEST, PKEY enable_rand = yes
Создание ключевой пары на USB-токене
Чтобы не вводить идентификатор системного диска вручную, запишем его значение в переменную UUID. Нам так же потребуется это значение без дефисов UUID_DIGITS и в формате строки байтов UUID_BYTES.
UUID=$(sudo blkid --match-token TYPE=crypto_LUKS --output value -s UUID) UUID_DIGITS=$(echo $UUID | sed 's/-//g') UUID_BYTES=$(echo -n $UUID_DIGITS | sed 's/-//g' | fold -w 2 | sed 's/^/%/g' | tr -d '\r\n') echo $UUID vs $UUID_DIGITS vs $UUID_BYTES
Результат выполнения команд...
localadmin@pc:~$ UUID=$(sudo blkid --match-token TYPE=crypto_LUKS --output value -s UUID) localadmin@pc:~$ UUID_DIGITS=$(echo $UUID | sed 's/-//g') localadmin@pc:~$ UUID_BYTES=$(echo -n $UUID_DIGITS | sed 's/-//g' | fold -w 2 | sed 's/^/%/g' | tr -d '\r\n') localadmin@pc:~$ echo $UUID vs $UUID_DIGITS vs $UUID_BYTES 453fa939-a585-4e1f-a030-b11991a78d3f vs 453fa939a5854e1fa030b11991a78d3f vs %45%3f%a9%39%a5%85%4e%1f%a0%30%b1%19%91%a7%8d%3
Перед началом использования устройства инициализируем токен:
rtadmin format --no-log --repair --label "Rutoken" \ --new-so-pin 16613403 --new-user-pin 20439756 \ --max-so-pin-retry-count 5 --max-user-pin-retry-count 10 \ --min-so-pin 8 --min-user-pin 8 \ --pin-change-policy user
Ключевую пару ГОСТ Р 34.10-2012 на токене создадим следующей командой:
pkcs11-tool --login --pin 20439756 --keypairgen \ --key-type GOSTR3410-2012-256:B --usage-derive \ --id $UUID_DIGITS \ --module /usr/lib/librtpkcs11ecp.so
, где:
--key-type— устанавливает тип эллиптической кривой GOSTR3410-2012-256:B;--usage-derive— определяет, что на закрытый ключ должен быть установлен флаг derive, который позволяет использовать его для формирования общего ключа симметричного шифрования.
Для ГОСТ Р 34.10-2012 доступно два поколения ключей:
GOSTR3410:{A, B, C} или более полно GOSTR3410-2001:{A, B, C} — стандарт от 2001 года с закрытыми ключами длиной 256 бит. Наборы параметров A, B и C обладают сопоставимой криптостойкостью и дают только вариативность. Стандарт считается устаревшим, не разрешен для применения и заменен на новый;
GOSTR3410-2012-256:{A, B, C, D} и GOSTR3410-2012-512:{A, B, C} — стандарт от 2012 года с закрытыми ключами длиной 256 и 512 бит соответственно. При обновлении стандарта был изменен алгоритм хеширования и добавлены 512-битных ключи, что привело также к добавлению новых эллиптических кривых.
Ключи длиной 512 бит пока еще считаются избыточными, а из 256-битных ключей наибольшую популярность получила эллиптическая кривая GOSTR3410-2012-256:B, которой соответствует набор параметров id-GostR3410-2001-CryptoPro-A-ParamSet, поэтому мы рекомендуем использовать именно эту кривую. Обратим еще раз внимание, что набору параметров A соответствует эллиптическая кривая B, а о том, как это получилось, вы можете узнать из статьи «История возникновения многообразия».
Для подтверждения того, что ключевая пара была успешно сгенерирована на USB-токене, можем найти ее в списке объектов:
pkcs11-tool --login --pin 20439756 --list-objects \ --module /usr/lib/librtpkcs11ecp.so
Результат выполнения команды...
localadmin@pc:~$ pkcs11-tool --login --pin 20439756 --list-objects \ > --module /usr/lib/librtpkcs11ecp.so Using slot 0 with a present token (0x0) Private Key Object; GOSTR3410-2012-256 PARAMS OID: 06072a850302022301 label: ID: 453fa939a5854e1fa030b11991a78d3f Usage: sign, derive Access: sensitive, always sensitive, never extractable, local Allowed mechanisms: GOSTR3410,GOSTR3410-WITH-GOSTR3411-12-256,GOSTR3410-DERIVE,GOSTR3410-12-DERIVE
Извлечь из USB-токена можно только открытый ключ, для этого можно воспользоваться утилитой openssl:
openssl pkey -in "pkcs11:id=$UUID_BYTES?pin-value=20439756" -inform engine -engine rtengine \ -pubout -out pair1_gostpub.pem
, где:
pkey— команда для работы с ключами, см. man openssl-pkey;-inform— определяет формат входящего файла. Обычно используют форматыDERилиPEM, но в приведенном примере указано значениеengine, которое определяет, что будет выполнено обращение к внешнему модулю;-engine— определяет идентификатор внешнего модуля, который будет использован для всех доступных алгоритмов. В приведенном примере мы используем модуль rtengine, который настроили ранее в файле/usr/lib/ssl/openssl.cnf;-in— указывает имя входящего файла. В приведенном примере в качестве имени используется строка URI, которая определяет адрес объекта на USB-токене, см. https://datatracker.ietf.org/doc/html/rfc7512. В строке URI используются два параметра:id— определяет идентификатор объекта на токене (ключа);pin-value— позволяет передать PIN-код, которым защищен объект на токене;
-pubout— определяет, что следует вывести открытый ключ. Без этого параметра утилита попытается по умолчанию извлечь и вывести закрытый ключ, что закончится ошибкой;-out— определяет имя выходного файла для записи ключа.
При желании параметры открытого ключа можно посмотреть с помощью ключа -text_pub:
openssl pkey -in "pkcs11:id=$UUID_BYTES?pin-value=20439756" \ -inform engine -engine rtengine \ -text_pub -noout
Результат выполнения команды
localadmin@pc:~$ openssl pkey -in "pkcs11:id=$UUID_BYTES?pin-value=20439756" \ > -inform engine -engine rtengine \ > -text_pub -noout engine "rtengine" set. Public key: X:26820B44A03D1FA514755C87CF52EEFB26AB425FEC77D1DBEAF627824078466E Y:9B2CECF1648AFA787F4F45493576FFA19C6743998E89D5DC8E45D4FB3CD05A9E Parameter set: id-GostR3410-2001-CryptoPro-A-ParamSet
Если потребуется удалить ключевую пару из токена, то закрытую и открытую части нужно будет удалять по отдельности с помощью команды --delete-object.
Пример команд для удаления ключей...
pkcs11-tool --login --pin 20439756 --delete-object \ --type=privkey --id $UUID_DIGITS \ --module /usr/lib/librtpkcs11ecp.so pkcs11-tool --login --pin 20439756 --delete-object \ --type=pubkey --id $UUID_DIGITS \ --module /usr/lib/librtpkcs11ecp.so
Для формирования общего ключа симметричного шифрования нам потребуется открытый и закрытый ключ. Мы, конечно, можем использовать открытый ключ той же пары, что уже создана на USB-токене, но правильнее будет использовать ключи все-таки от разных пар. Вторую пару можно создать также на USB-токене с помощью приведенных выше команд или с использованием утилиты openssl следующим образом:
openssl genpkey -out pair2_gostpriv.pem -algorithm gost2012_256 \ -pkeyopt paramset:id-GostR3410-2001-CryptoPro-A-ParamSet
, где:
genpkey— команда для генерации закрытого ключа;-out— имя выходного файла;-algorithm— алгоритм для формирования ключа, используетсяgost2012_256;-pkeyopt— позволяет задать дополнительные параметры открытого ключа в формате параметр:значение.Для возможности согласования общего ключа симметричного шифрования нам требуются ключевые пары с одинаковыми параметрами эллиптической кривой. Но если при генерации ключевой пары с помощью утилиты
pkcs11-toolмы указывали тип эллиптической кривой GOSTR3410-2012-256:B, то при генерации ключевой пары утилитой openssl нам нужно указать набор параметров id-GostR3410-2001-CryptoPro-A-ParamSet, который соответствует этой кривой. О том, почему кривой B соответствует набор параметров A, как мы уже говорили ранее, вы можете узнать из статьи «История возникновения многообразия».
Вычислим открытый ключ для сгенерированного закрытого ключа:
openssl pkey -in pair2_gostpriv.pem -pubout -out pair2_gostpub.pem
Общий ключ симметричного шифрования с использованием закрытого ключа на токене можно рассчитать следующей командой:
openssl pkeyutl --derive \ -keyform engine -engine rtengine \ -inkey "pkcs11:id=$UUID_BYTES?pin-value=20439756" \ -peerkey pair2_gostpub.pem \ -pkeyopt ukmhex:DeadBeefDeadBeef \ -out symmetric-key.der
, где:
openssl-pkeyutl— команда для выполнения низкоуровневых операций с ключами;--derive— указывает, что нужно рассчитать общий ключ симметричного шифрования;-keyform— определяет формат ключа, допускает значенияPEM,DERилиENGINE;-engine— определяет идентификатор внешнего модуля, который будет использован для всех доступных алгоритмов;-inkey— определяет имя файла с закрытым ключом в формате URI-адреса на USB-токене;-peerkey— определяет имя файла с открытым ключом;-pkeyopt — позволяет задать дополнительные параметры открытого ключа в формате параметр:значение.
Параметр
ukmhexопределяет дополнительный материал ключа пользователя (англ. User Keying Material, UKM) в шестнадцатеричном формате (англ. Hexadecimal, HEX), который будет использован для формирования общего ключа симметричного шифрования. Строка должна быть длиной не менее 16 символов (8 байт) и может включать любую дополнительную информацию, специфичную для приложения. Например, для повышения безопасности обмена данными между клиентом и сервером в каждой пользовательской сессии может быть назначено уникальное значение UKM, сгенерированное случайным образом.Учитывая, что по нашей схеме закрытый ключ USB-токена нужен только для разблокирования системного диска, параметр
ukmhexможно было бы и не использовать. Однако для алгоритма ГОСТ Р 34.10-2012 этот параметр является обязательным, поэтому в качестве фиксированной последовательности символов мы можем взять Hexspeak-строку «DeadBeef», которую используют, например, для еще неинициализированной памяти. Фанатам Java можно предложить последовательность «CafeBabe», которая используется в качестве сигнатуры объектных файлов, а для олдов отлично подойдет «1ce1ceBabe».
-out— определяет имя выходного файла для записи ключа.
Воспользуемся ключом симметричного шифрования в качестве пользовательского ключа LUKS для шифрования мастер-ключа. Добавим ключ с помощью следующей команды:
sudo cryptsetup luksAddKey /dev/sda5 symmetric-key.der
Хранение данных в заголовке LUKS
Для расчета общего ключа симметричного шифрования кроме закрытого ключа на USB-токене потребуется открытый ключ второй ключевой пары и значение параметра ukmhex. Если в качестве ukmhex использовать фиксированное значение, то в заголовке LUKS достаточно хранить только открытый ключ pair2_gostpub.pem. Способ хранения будем использовать тот же, что и для RSA.
Если вы ранее уже добавили запись в раздел tokens заголовка LUKS, то это можно будет увидеть с помощью команды luksDump:
sudo cryptsetup luksDump /dev/sda5
Результат выполнения команды...
localadmin@pc:~$ sudo cryptsetup luksDump /dev/sda5 LUKS header information ... Tokens: 1: aldpro-rutoken Keyslot: 1 ...
Удалить старую запись можно будет командой token remove:
sudo cryptsetup token remove /dev/sda5 --token-id 1
Записать новые данные в заголовок можно с помощью команды token import утилиты cryptsetup:
sudo cryptsetup token import /dev/sda5 --token-id 1 <<EOF { "type": "aldpro-rutoken", "keyslots": ["1"], "gostpub": "$(base64 --wrap=0 pair2_gostpub.pem)", } EOF
Для извлечения токена можно воспользоваться командой token export:
localadmin@pc:~$ sudo cryptsetup token export /dev/sda5 --token-id 1 {"type":"aldpro-rutoken","keyslots":["1"],"gostpub":"LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUdZd0h3WUlLb1VEQndFQkFRRXdFd1lIS29VREFnSWpBUVlJS29VREJ3RUJBZ0lEUXdBRVFITkJIMUZzeVMxKwpHcWRodmNrd0g5ZEQwWWp2K3h6dlluV2lkeE00NDh3VUQ5ZUVIMWgvTEZHRkIzRkVIZ1h3Y01wc3ltMEhabGROClROdXBjM1V5SkZZPQotLS0tLUVORCBQVUJMSUMgS0VZLS0tLS0K"}
Скрипт для работы с USB-токенами на алгоритмах ГОСТ Р 34.10-2012
Добавим опцию keyscript в файл /etc/crypttab, чтобы система запрашивала пользовательский ключ с помощью нашего кастомного скрипта:
# Удалим параметр keyscript из конца строк, если он есть sudo sed -i 's|,keyscript=.*||' /etc/crypttab # Добавим параметр keyscript с нужным нам значением sudo sed -i 's|$|,keyscript=/bin/unlock_luks_with_token|' /etc/crypttab # Проверим результат cat /etc/crypttab
Результат выполнения команд...
localadmin@pc:~$ sudo sed -i 's|,keyscript=.*||' /etc/crypttab localadmin@pc:~$ sudo sed -i 's|$|,keyscript=/bin/unlock_luks_with_token|' /etc/crypttab localadmin@pc:~$ cat /etc/crypttab sda5_crypt UUID=453fa939-a585-4e1f-a030-b11991a78d3f none luks,discard,keyscript=/bin/unlock_luks_with_token
Создадим или модифицируем скрипт unlock_luks_with_token для разблокирования системного диска с помощью USB-токена на алгоритмах ГОСТ Р 34.10-2012:
Файл /bin/unlock_luks_with_token
#!/bin/sh set +e # Выключаем выход из скрипта при ошибке # Переключаемся в текстовый режим и устанавливаем кириллический шрифт /usr/bin/plymouth hide-splash setfont /usr/share/consolefonts/CyrSlav-Fixed16.psf.gz >&2 # Возвращаем графический интерфейс /usr/bin/plymouth show-splash check_token() { # Если токен отсутствует, код возврата будет равен единице /usr/bin/opensc-tool -n >/dev/null 2>&1; TOKEN_NOT_FOUND=$? } get_enc_data() { PARTITION=$CRYPTTAB_SOURCE HDR_SIZE=$(od -A n --endian=big -t d8 -j 8 -N 8 $PARTITION 2>/dev/null) JSON_SIZE=$(( HDR_SIZE - 4096 )) JSONDATA=$(dd if=$PARTITION bs=1 skip=4096 count=$JSON_SIZE 2>/dev/null | sed 's/\x0//g' ) GOSTPUB=$(echo $JSONDATA | jq -r '[.tokens[] | select(.type == "aldpro-rutoken")][0].gostpub') } read_pass_from_keyboard(){ if [ ${#PASS} -eq 0 ]; then /usr/bin/plymouth display-message --text="Разблокирование диска с помощью пароля" /usr/bin/plymouth display-message --text="Вы можете нажать клавишу <Enter>, чтобы переключиться на загрузку с помощью USB-токена" PASS=$(/usr/bin/plymouth ask-for-password --prompt="Введите пароль" | base64) if [ ${#PASS} -eq 0 ]; then return 0 fi fi } read_pass_from_token(){ /usr/bin/plymouth display-message --text="Разблокирование диска с помощью USB-токена" check_token if [ $TOKEN_NOT_FOUND = 1 ]; then /usr/bin/plymouth display-message --text="Не удалось найти USB-токен" return 0 fi /usr/bin/plymouth display-message --text="USB-токен подключен к компьютеру" get_enc_data /usr/bin/plymouth display-message --text="Парсинг заголовка LUKS выполнен успешно" if [ $GOSTPUB = "null" ]; then /usr/bin/plymouth display-message --text="Не удалось найти данные для USB-токена в заголовке LUKS" return 0 fi /usr/bin/plymouth display-message --text="Данные USB-токена найдены в заголовке LUKS" while [ ${#PASS} -eq 0 ]; do /usr/bin/plymouth display-message --text="Вы можете нажать клавишу <Enter>, чтобы переключиться на загрузку с помощью пароля" PIN=$(/usr/bin/plymouth ask-for-password --prompt="Введите PIN-код от USB-токена") if [ ${#PIN} -eq 0 ]; then return 0 fi echo $GOSTPUB | base64 -d > /tmp/gostpub.pem PKCS11ID=$(echo -n $UUID | sed -e 's/-//g' | fold -w 2 | sed 's/^/%/g' | tr -d '\r\n') PASS=$(/usr/bin/openssl pkeyutl --derive -keyform engine -engine rtengine -inkey "pkcs11:id=$PKCS11ID?pin-value=$PIN" -peerkey /tmp/gostpub.pem -pkeyopt ukmhex:deadbeefdeadbeef -out /tmp/opensslpipe >&2 2>/dev/null && base64 /tmp/opensslpipe) if [ $? -ne 0 ]; then /usr/bin/rtadmin info >&2 /usr/bin/plymouth display-message --text="Неверный PIN-код" PASS= else /usr/bin/plymouth display-message --text="Пользовательский ключ успешно извлечен, для продолжения загрузки требуется извлечь USB-токен..." while true; do sleep 1 check_token if [ $TOKEN_NOT_FOUND = 1 ]; then /usr/bin/plymouth display-message --text="USB-токен извлечен, продолжаем загрузку" return 0 fi done fi done } PASS= UUID=$(blkid -s UUID -o value $CRYPTTAB_SOURCE) /usr/bin/plymouth display-message --text="Пробуем разблокировать диск $UUID" while [ ${#PASS} -eq 0 ]; do read_pass_from_token read_pass_from_keyboard done echo -n "$PASS" | base64 -d
Сделаем скрипт исполняемым:
sudo chmod +x /bin/unlock_luks_with_token
Для возможности использования утилит pkcs, jq, rtengine и других файлов на ранних стадиях загрузки системы создадим или модифицируем хук unlock_luks_with_token_hook:
Файл /etc/initramfs-tools/hooks/unlock_luks_with_token_hook
#!/bin/sh PREREQ="" prereqs() { echo "$PREREQ" } add_file() { # Удаляем файл, если такой уже есть, поскольку функция copy_exec не умеет перезаписывать существующие файлы rm -f ${DESTDIR}$1 # Добавляем указанный файл в initramfs copy_exec $1 $1 } add_package() { for fname in `/usr/bin/dpkg -L $1`; do if [ -f "$fname" ]; then add_file "$fname" else mkdir -p "${DESTDIR}$fname" fi done } case $1 in prereqs) prereqs exit 0 ;; esac # Подключаем скрипт с функцией copy_exec . /usr/share/initramfs-tools/hook-functions # Добавляем файлы для возможности использования кириллического шрифта CyrSlav-Fixed16.psf.gz add_package console-setup-linux # Добавляем файлы для использования утилиты setfont add_package kbd # Добавляем файлы для использования утилит base64, dd, od add_package coreutils # Добавляем файлы для использования утилиты openssl add_package openssl # Добавляем файлы для использования утилиты jq add_package jq # Добавляем файлы службы, управляющей подключениями к смарт-картам add_package pcscd mkdir -p ${DESTDIR}/var/run/pcscd # Добавляем файлы библиотеки, предоставляющей программные интерфейсы Windows(R) SCard для доступа к смарт-картам add_package libpcsclite1 # Добавляем файлы библиотеки, реализующей интерфейс обработчика устройств add_package libccid # Добавляем файлы библиотеки для работы с Рутокен ЭЦП по стандарту PKCS#11 add_package librtpkcs11ecp mkdir -p ${DESTDIR}/tmp # Добавляем файл утилиты rtadmin add_file /usr/bin/rtadmin # Добавляем файлы утилит, включая pkcs11-tool и opensc-tool, которые упрощают работу со смарт-картами add_package opensc # Добавляем файлы для возможности использования rtengine add_file /usr/lib/rtengine/1.6.2/Linux/x64/lib/librtengine.so add_file /usr/lib/rtengine/1.6.2/Linux/x64/lib/librtengine.so.1.6.2 add_file /usr/lib/x86_64-linux-gnu/engines-1.1/gost.so add_file /usr/lib/x86_64-linux-gnu/engines-1.1/gost.so.1.1 add_file /usr/lib/ssl/openssl.cnf
Сделаем файл хука исполняемым:
sudo chmod +x /etc/initramfs-tools/hooks/unlock_luks_with_token_hook
Для возможности работы с USB-токенами в ядро initramfs нужно включить модуль opensc, для чего в файл /etc/initramfs-tools/modules требуется добавить следующие строки:
Файл /etc/initramfs-tools/modules
... # Модуль для работы с USB-токенами opensc
Соберем образ initramfs:
sudo update-initramfs -u
Если вы еще не читали первую часть статьи, то выполните дополнительно следующие команды, чтобы настроить plymouth. Мы рекомендуем использовать тему spinner, которая отображает текстовые сообщения в центре экрана под индикатором загрузки, что делает их достаточно заметными.
sudo apt install --yes plymouth-themes sudo plymouth-set-default-theme spinner --rebuild-initrd sudo sed -i 's|"quiet|"splash quiet|' /etc/default/grub sudo update-grub
И можно проверять. Но главное, не забывайте, что кроме технических средств у злоумышленников есть еще средства прямого воздействия, поэтому следи за собой, будь осторожен!

Вместо заключения
Как мы уже говорили в третьей части статьи, использование USB-токенов нам кажется более привлекательным, чем модулей TPM, поскольку последние произведены за границей и не обладают достаточным уровнем доверия. Одним из наиболее перспективных направлений для дальнейшего развития является реализация параметра групповой политики для обеспечения централизованного управления ключами LUKS через службу каталога. В домене ALD Pro уже есть параметр LAPS для управления паролями локальных администраторов и паролями GRUB2 и возможность управления ключами LUKS станет отличным дополнением, поскольку поможет в восстановлении доступа к данным при утере парольной фразы или USB-токена. Но это будет уже совсем другая история.
