Полное руководство: работа с криптоконтейнерами и подписями в CryptoPro CSP (Linux)

  • Михаил
  • 8 мин. на прочтение
  • 13
  • 30 May 2026
  • 30 May 2026

⚠️ Важно: Инструкция рассчитана на CryptoPro CSP 5.0+ для Linux. Все команды выполняются в терминале. Если ключ на токене имеет атрибут Экспортируемый: Нет, копирование приватной части невозможно на уровне драйвера и CSP (это ограничение сертификации ФСТЭК/ФСБ). Инструкция предполагает, что ключ разрешает выгрузку.


📦 0. Подготовка и проверка окружения

Установите необходимые пакеты

# Debian/Ubuntu
sudo apt install cprocsp-rdr-pcsc cprocsp-cptools cprocsp-cryptcp

# RHEL/CentOS/Alma/Rocky
sudo yum install cprocsp-rdr-pcsc cprocsp-cptools cprocsp-cryptcp

Проверьте версию CSP

/opt/cprocsp/bin/amd64/cpconfig -license -view

Убедитесь, что служба PC/SC запущена (для токенов)

sudo systemctl start pcscd
sudo systemctl enable pcscd

🔍 1. Поиск контейнеров и проверка экспортируемости

# Вывести все доступные контейнеры с полными путями
/opt/cprocsp/bin/amd64/csptest -keyset -enum_cont -verifycontext -fqcn

Пример вывода:

\\.\RUTOKEN\MyGost2012Container

\\.\HDIMAGE\AnotherContainer

Проверьте, разрешён ли экспорт приватного ключа

CONT="\\.\RUTOKEN\MyGost2012Container"
/opt/cprocsp/bin/amd64/certmgr -list -cont "$CONT" -v | grep -i -A2 "Свойства ключа"

Ищите строку: Ключ экспортируемый: Да. Если Нет → копирование невозможно.


📥 2. Копирование контейнера с токена на диск

КриптоПро использует виртуальные пути. HDIMAGE = файловая система (~/.cprocsp/keys/).

SRC="\\.\RUTOKEN\MyGost2012Container"
DEST="\\.\HDIMAGE\MyGost2012Container"

/opt/cprocsp/bin/amd64/certmgr -copy -src "$SRC" -dest "$DEST"

🔹 Что произойдёт:

  • Запросит PIN-код токена (если установлен)
  • Запросит пароль на новый контейнер (можно оставить пустым, но рекомендуется)
  • Скопирует header.key, primary.key, masks.key в ~/.cprocsp/keys/$(id -u)/MyGost2012Container/

💡 Альтернатива через csptest (полезно для скриптов):

/opt/cprocsp/bin/amd64/csptest -keyset -copy -src "$SRC" -dest "$DEST" -pin <PIN_ТОКЕНА> -newpin <ПАРОЛЬ_НОВОГО>

🔐 3. Настройка прав и проверка работоспособности

КриптоПро CSP строго проверяет права на файлы ключей. Нарушение → 0x8009000B или Access denied.

KEY_DIR="$HOME/.cprocsp/keys/$(id -u)/MyGost2012Container"

# Только владелец имеет доступ
chmod -R 700 "$KEY_DIR"
chown -R "$(id -un):$(id -gn)" "$KEY_DIR"

Проверка доступа и привязки к сертификату

/opt/cprocsp/bin/amd64/csptest -keyset -cont '\\.\HDIMAGE\MyGost2012Container' -verify
/opt/cprocsp/bin/amd64/certmgr -list -cont '\\.\HDIMAGE\MyGost2012Container'

Если команды завершились без ошибок → контейнер готов к использованию без токена.


✍️ 4. Создание подписей (3 типа)

Для подписи используется cryptcp. Убедитесь, что он установлен: /opt/cprocsp/bin/amd64/cryptcp -?

🔑 Получите Thumbprint (SHA1) сертификата (опционально, но удобно):

certmgr -list -cont '\\.\HDIMAGE\MyGost2012Container' | grep -i "SHA1 hash" | awk '{print $NF}'

В примерах ниже используется -cont, так как он надёжнее привязывается к приватному ключу.

📎 4.1. Присоединённая подпись (Attached / P7S)

Файл и подпись объединяются в один контейнер (обычно .p7s или .sig).

INPUT="document.pdf"
OUTPUT="document.pdf.p7s"

/opt/cprocsp/bin/amd64/cryptcp -signf \
  -cont '\\.\HDIMAGE\MyGost2012Container' \
  -detached no \
  -pin "" \
  "$INPUT" "$OUTPUT"

📌 Результат: document.pdf.p7s содержит и исходные данные, и подпись. Открывается в КриптоПро ARM, браузерах с плагином.

📄 4.2. Отсоединённая подпись (Detached)

Подпись сохраняется в отдельный файл. Исходный файл не изменяется.

OUTPUT_SIG="document.pdf.sig"

/opt/cprocsp/bin/amd64/cryptcp -signf \
  -cont '\\.\HDIMAGE\MyGost2012Container' \
  -detached yes \
  -pin "" \
  "$INPUT" "$OUTPUT_SIG"

📌 Результат: document.pdf (оригинал) + document.pdf.sig (бинарная CMS-подпись). Стандарт для ЭДО и госпорталов.

🔹 4.3. Raw-подпись (Сырая)

Только зашифрованный хэш без ASN.1-обёртки и метаданных сертификата. Используется в низкоуровневых протоколах.

OUTPUT_RAW="document.pdf.raw"

/opt/cprocsp/bin/amd64/cryptcp -signf \
  -cont '\\.\HDIMAGE\MyGost2012Container' \
  -detached yes \
  -raw yes \
  -pin "" \
  "$INPUT" "$OUTPUT_RAW"

📌 Результат: Бинарный блок фиксированной длины (64/128 байт для ГОСТ). Не содержит информации о сертификате! При проверке сертификат должен быть уже установлен в хранилище.


🔎 5. Проверка подписей (все 3 типа)

VERIFY_CMD="/opt/cprocsp/bin/amd64/cryptcp -verifyf -verifychain -all"

✅ 5.1. Проверка присоединённой подписи

$VERIFY_CMD document.pdf.p7s

🔍 Вывод покажет статус валидации, цепочку УЦ, срок действия, отклики CRL/OCSP.

✅ 5.2. Проверка отсоединённой подписи

$VERIFY_CMD -detached yes document.pdf.sig document.pdf

🔹 Первый аргумент → файл подписи, второй → исходный файл.

✅ 5.3. Проверка Raw-подписи

$VERIFY_CMD -detached yes -raw yes document.pdf.raw document.pdf

⚠️ Важно: Для успешной проверки Raw-подписи сертификат, которым она создана, должен быть установлен в хранилище Личные или Доверенные. Иначе будет ошибка Не найден сертификат.

Установить сертификат в хранилище (если есть .cer):

/opt/cprocsp/bin/amd64/certmgr -inst -file cert.cer -cont '\\.\HDIMAGE\MyGost2012Container'

6. Чек-лист и типичные ошибки

 

Ошибка / Ситуация

Причина

Решение

0x8009000B / Key is not exportable

Ключ аппаратно защищён

Копирование невозможно. Перевыпустите сертификат с флагом экспорта или работайте через токен.

Access denied при -verify

Неверные права на папку ключей

chmod -R 700 ~/.cprocsp/keys/$(id -u)/<Name> + chown

Не найден сертификат при проверке

Сертификат не установлен или удалён

certmgr -inst -file cert.cer или используйте -cont при подписи

Цепочка не проверена

Нет доступа к CRL/OCSP УЦ

Добавьте -noverifychain для отладки или настройте доступ к интернету/локальным спискам

PIN-код запрашивается каждый раз

Не передан параметр -pin или контейнер запаролен

Добавьте -pin "12345678" в команды или настройте кеширование PIN через cpconfig


📜 7. Готовый Bash-скрипт-обёртка

#!/bin/bash
set -e

CONT="\\.\HDIMAGE\MyGost2012Container"
PIN="${CRYPTO_PIN:-}"
FILE="${1:-test.pdf}"

echo "📦 Проверка контейнера..."
/opt/cprocsp/bin/amd64/csptest -keyset -cont "$CONT" -verify -quiet

echo "🔑 Подписание (присоединённая)..."
cryptcp -signf -cont "$CONT" -detached no -pin "$PIN" "$FILE" "${FILE}.p7s"

echo "📄 Подписание (отсоединённая)..."
cryptcp -signf -cont "$CONT" -detached yes -pin "$PIN" "$FILE" "${FILE}.sig"

echo "🔹 Подписание (raw)..."
cryptcp -signf -cont "$CONT" -detached yes -raw yes -pin "$PIN" "$FILE" "${FILE}.raw"

echo "✅ Проверка присоединённой..."
cryptcp -verifyf -verifychain -all "${FILE}.p7s"

echo "✅ Проверка отсоединённой..."
cryptcp -verifyf -detached yes -verifychain -all "${FILE}.sig" "$FILE"

echo "✅ Проверка raw..."
cryptcp -verifyf -detached yes -raw yes -verifychain -all "${FILE}.raw" "$FILE"

echo "🎉 Все операции выполнены успешно."

Сделайте исполняемым: chmod +x crypto_ops.sh
Запуск: ./crypto_ops.sh document.pdf (можно задать CRYPTO_PIN=12345678 ./crypto_ops.sh doc.pdf)


📌 Рекомендации для продакшена

  1. Никогда не храните PIN в открытом виде. Используйте systemd-creds, HashiCorp Vault или read -s в интерактивных скриптах.
  2. Регулярно обновляйте списки отозванных сертификатов: cpconfig -crl -update
  3. Для автоматизации предпочтительнее использовать thumbprint вместо -cont, если контейнеры мигрируют между серверами.
  4. Логи: Добавьте -log <файл> к cryptcp для аудита: cryptcp -signf ... -log /var/log/crypto_sign.log