Я уже кратко писал на форуме об опыте тестировании новой Джакарты, но, подумав, захотелось поподробнее рассказать о полученных в процессе этого результатах.
В приложение, которое уже поддерживает работу с подписью на носителе JaCarta ГОСТ, нужно встроить поддержку JaCarta ГОСТ 2 для работы с ГОСТ 34.10-2012.
Что произойдет и какие косяки:
Основная проблема с которой можно столкнуться - неоднозначность примеров в SDK.
Во-первых, примеры привязаны к конкретным моделям устройств. Понять, можно ли использовать один и тот же пример для разных моделей или нет достаточно нетривиально (придется сравнивать файлы по строкам). Впрочем, если и удалось встроить JaCarta ГОСТ, то значит, что с этим как-то и можно разобрался.
Во-вторых, некоторые примеры почему-то отсутствуют - версия GOST_PKCS7SignAndVerify для ГОСТ 34.10-2012 отсутствует, хотя и является одной из самых используемых при разработке
Мелочь, но странно - примеры оформлены разном стиле и в комментариях используют разную терминологию (где-то ЭП, где-то ЭЦП; написано, что делаем Login пользователем, а потом почему-то Logout администратором). Некомпетентного разработчика это может слегка смутить.
Дальше про ИКБ. Примеры для ИКБ идут как бы дополнением. При этом работы с ИКБ в коде больше обусловлена безопасностью и правилами пользования.
Сам код работы внутри ИКБ практически не отличается.
Выключение работы с ИКБ внутри себя вызывает Logout. Это совсем не очевидно и может местами поломать работу с токенами.
Все примеры в новом SDK построены таким образом, что отдельно демонстрируют работу с хешом и отдельно работу с подписью. Что делать при уже выявленном хеш - совсем непонятно.
Для старого ГОСТ пример выглядит так
// буффер с данными для подписания
CK_BYTE data[32];
Известно, что 32 байта это как раз размер хеша. Может быть подписан как хеш так и данные. Но в примере для нового ГОСТ уже написано:
// буффер с данными (не хешем) для подписания
CK_BYTE data[128];
Фактически для одного токена, но разных алгоритмов придется реализовывать разный код.
На этом стоит остановиться чуть подробнее. Вычисление хеш отдельно типичная операция. Наиболее она типична для клиент-серверных систем, в которых пользователь загружает документ на сервер, а затем подписывает. Очевидно, что в таком случае лучше вычислять хеш на сервере, а потом передавать его на подпись клиенту (сервер считает быстрее токена и документ не надо гонять туда сюда, что для документов размеров в 100 Мб и выше значительно замедляет работу). Такой сценарий с новой Jacarta не реализуется в принципе.
Стоит также отметить, что переключение между программным и аппаратным хеш происходит вразрез с документами ТК-26 - вместо использования параметров C_DigestInit необходимо использовать специальную функцию. А значит множество ПО, которое ранее поддерживало Jacarta ГОСТ при переходе на JaCarta ГОСТ 2 автоматически будет считать хеш только аппаратно, что неизбежно приведет к торможениям работы при работе с документами в 1Мб и выше. Выглядит это так
rv = CALL_EXT(JC_CT2_SetCertificatedMode(nGostSlotId, CK_TRUE));
if (rv != CKR_OK)
{
bICLFound = false;
}
else
{
mech.mechanism = CKM_GOSTR3411_12_256;
mech.pParameter = NULL_PTR;
mech.ulParameterLen = 0;
rv = CALL_P11(C_DigestInit(hSession, &mech));
При этом на том же токене, но со старым хеш или со старым токеном можно просто выполнить:
mech.mechanism = CKM_GOSTR3411;
mech.pParameter = NULL_PTR;
mech.ulParameterLen = 0;
rv = CALL_P11(C_DigestInit(hSession, &mech));