Специфика использования отдельно хранящихся симметричных ключей при шифровании с помощью Utils.exe В Utils.exe реализована возможность шифровать и подписывать, расшифровывать и проверять подпись как с помощью секретного и публичного ключей, хранимых в файлах (в этом случае за безопасность ключевого носителя отвечает сам пользователь), так и с помощью сертификатов в хранилище CryptoAPI. При этом параметры Symmetric Key File/Symmetric Key закладок Request и Crypt в диалогах Utils.exe задаются пустыми, т.к. при шифровании симметричный (сессионный) ключ, как обычно, автоматически генерируется в памяти и вкладываемый в зашифрованное сообщение, а на другой стороне извлекается в памяти из зашифрованного сообщения и используется при дешифрации. В Utils.exe также реализована возможность явной генерации пользователем симметричных ключей и задания в параметрах Symmetric Key File/Symmetric Key закладок Request и Crypt при шифрации и дешифрации. Но использование симметричных ключей с их явным заданием ограничено только одним специализированным вариантом (потребовавшимся разработчику на практике), при котором на сервере секретный и публичный ключи хранятся именно в файлах и есть публичный ключ клиента в виде файла, у клиента используются именно сертификаты, установленные в стандартное хранилище сертификатов, и есть сертификат с публичным ключом сервера, установленный в хранилище, симметричные ключи при этом генерируются только сервером, перешифровываются на публичных ключах клиентов и распространяются клиентам (отдельно от зашифрованных сообщений). Впрочем, код GCryAPI.pas несложно доработать для других вариантов, при которых явно используются симметричные ключи. Для тестирования данного варианта можно проделать следующую последовательность действий в Utils.exe. 1) В закладке Request утилиты вверху ввожу в Common Name имя сертификата, скажем, ClientCert1, задаю алгоритм, например, GOST94, нажимаю Request вверху справа - для генерации секретного ключа и запроса на сертификат c:\certreq.txt (также копия открытого ключа из запрса на сертификат сохраняется отдельно - в файл c:\key.pub, вручную переименую этот файл в c:\client.pub, чтобы далее он не затерся). 2) Нажимаю Issue (Центр сертификации расположен на этой же машине; если на удаленной, то его имя можно задать в CA Name в формате имя_машины\имя_ЦС) - по запросу c:\certreq.txt выпускается сертификат c:\cert.cer. 3) Нажимаю Accept - сертификат c:\cert.cer устанавливается в хранилище личных сертификатов и связывается с созданным в п.1. личным секретным ключом. 4) Нажимаю Generate внизу справа - создаются секретный и публичный ключи и записываются в файлы c:\key.prv и c:\key.pub. 5) В Common Name вверху ввожу ServerCert, нажимаю нижнюю Request (внизу справа) - по публичному ключу c:\key.pub создается запрос на сертификат c:\certreq.txt. 6) Нажимаю Issue (Центр сертификации расположен на этой же машине; если на удаленной, то его имя можно задать в CA Name в формате имя_машины\имя_ЦС) - по запросу c:\certreq.txt выпускается сертификат c:\cert.cer. 7) Для установки c:\cert.cer в хранилище - кникнуть по нему и нажать Установить сертификат, Далее, Далее, Готово. 8) Итого для клиентской стороны у нас есть: сертификат клиента с секретным ключом в хранилище личных сертификатов + сертификат сервера в хранилище промежуточных. Для серверной стороны в данном варианте используются ключи в виде файлов, а не сертификатов в хранилище, и у нас есть: секретный и публичный ключи сервера c:\key.prv и c:\key.pub, публичный ключ клиента c:\client.pub Найдем сертификаты клиента и сервера и выпишем их серийные номера: в Internet Explorer, меню Сервис, Свойства обрзревателя, закладка Содержание, кнопка Сертификаты, закладка Личные, ClientCert1 - кликнуть по нему и во второй закладке выписать серийный номер, например, 2952 3C64 0001 0000 0009, закрыть диалог свойств сертификата, в закладке Промежуточные центры сертификации (куда попадают по умолчанию все сертификаты без серкетного ключа) находим ServerCert - кликнуть по нему и во второй закладке выписать серийный номер, например, 2980 101A 0001 0000 000D. 9) Создадим симметричный ключ - в данном варианте он создается только на сервере. Предполагается, что сервер взаимодействует с несколькими группами пользователей (например, организациями), для каждой организации сервером периодически создается отдельный симметричный ключ. Далее на сервере симметричный ключ организации перешифровывается на каждом из публичных ключей пользователей и экземпляры симметричного ключа распространяются пользователям. Поскольку симметричный ключ един для всей организации, то сообщение, зашифрованное сервером или любым из пользователей, может быть расшифровано любым другим пользователем данной организации или сервером. Для генерации на сервере симметричного ключа данной организации - в Utils.exe нажать Gen Sym. внизу справа - создается файл c:\key.sym (симметричный ключ, зашифрованный на ключах сервера; скопируем его в файл c:\server.sym). 10) Нажатием кнопки Recrypt внизу - перешифруем симметричный ключ для одного из пользователей организации, имеющего публичный ключ c:\client.pub (в результате в c:\key.sym имеем симметричый ключ, зашифрованный на парном ключе сервера и пользователя; такой ключ может быть расшифрован на стороне клиента). Таким образом, имеем симметричный ключ для стороны сервера c:\server.sym и для стороны клиента c:\key.sym. 11) В Utils.exe переходим в закладку Crypt, там выбираем тот же алгоритм (например, GOST94). На диске создаем файл с какими-нибудь данными c:\data. В Utils.exe в Data File вверху впишем c:\data, в Encrypted File - c:\enc (туда запишется зашифрованны c:\data), в Private Key впишем c:\key.prv, в Public Key впишем c:\key.pub, пометим галочку Symmetric Key и пишем в поле c:\server.sym (Client Public Key заполнять не нужно, т.к. симметричный ключ зашифрован только на ключах сервера, которые мы задали), нажмем Encrypt - в результате c:\data зашифровался, результат помещен в c:\enc 12) Расшифруем c:\enc у клиента. Для этого пометим галочку напротив Certificate Store (означающую, что будут использоваться сертификаты в храилище, а не файлы ключей), под Certificate Store и значением MY (личное хранилище сертификатов) в поле Serial Number впишем серийный номер собственного сертификата пользователя (в моем примере это 2952 3C64 0001 0000 0009, разделяющие пробелы убирать не обязательно, они проигнорируются), ниже под Client Cert. Store и значением CA (хранилище сертификатов без секретных ключей) в поле Serial Number впишем серийный номер сертификата сервера (в моем примере это 2980 101A 0001 0000 000D), убедимся, что напротив поля Symmetric Key стои галочка и впишем туда c:\key.sym - симметричный ключ, перешифрованный для пользователя. В Encrypted File оставляем c:\enc, в Data File впишем c:\datacli, нажмем Decrypt вверху справа - в результате c:\enc расшифровался с помощью сертификатов и симметричного ключа в c:\datacli (командой fc /b c:\data c:\datacli можем сравнить, что файлы идентичны). 13) Теперь зашифруем данные на стороне клиента (и расшифруем на стороне сервера). Для этого в Encrypted File впишем c:\enccli, сохраним заполнение остальных полей (галочка помечена напротив Certificate Store), нажмем Encrypt - в результате c:\datacli зашифровался в c:\enccli. 14) Для расшифровки файла пометим галочку напротив Private Key слева, в верхней части окна, чтобы использовались ключи, в Symmetric Key впишем c:\server.sym и изменим Data File на c:\datasrv, после чего нажмем Decrypt - файл от клиента расшифровался в c:\datasrv (можно проверить идентичность, запустив fc /b datacli datasrv).