Guardant API (SDK 7 Update6) для Delphi - проверка цифровой подписи

Вопрос по Guardant API (SDK 7 Update6) для Delphi

Имеются 2 локальных USB-ключа Guardant Code, отличающиеся друг от друга только ключами ECC160 (у т.е. у них разные и открытый и закрытый ключ ECC160 для алгоритма цифровой подписки).
Я пытаюсь выполнить аппаратное (с помощью USB-ключа и закрытого ключа шифрования) подписывание строки цифровой подписью и последующую программную проверку этой подписи с помощью открытого (Public) ключа:
1) инициализируем данную копию GrdAPI
2) создаем защищенный контейнер Grd и получаю его хэндл для использования в мультипоточном режиме
GrdCreateHandle(nil, GrdCHM_MultiThread, nil);
3) запоминаем известные нам коды доступа (публичный и чтения) в защищенном контейнере GuardantHandle
4) задаем режим поиска ключа по номеру программы, серийному номеру, номеру версии и битовой маске
5) ищем самый первый подходящий ключ GrdFind(hGrd, GrdF_First, @dwID, @GrdFindInfo);
6) в цикле
6.1) выполняем подключение к ключу GrdLogin(hGrd, $FFFFFFFF, GrdLM_PerStation);
6.2) подписываем некую строку с помощью ECC160 аппаратного USB-ключа GrdSign
6.3) проверяем цифровую подпись для этой строки (с помощью программного алгоритма на ПК)  VerifyECC160Sign(DataForSign, ECCSign)
6.4) если подпись не совпадает, то
6.4.1) отключаемся от ключа GrdLogout(hGrd, 0);
6.4.2) ищем следующий ключ GrdFind(hGrd, GrdF_Next, @dwID, @GrdFindInfo) – при этом получаемое содержимое dwID и структуры GrdFindInfo отличаются от тех, которые были получено на предыдущем вызове GrdFind;
6.4.3) повторяем цикл
(естественно, после вызова каждой функции API проводится проверка ошибок).
Так вот если к ПК подключен всего один ключ – все работает как ожидается.
Если ключа два, но только один из них «правильный» (т.е. с нужным ECC160) – то если «правильный» ключ обнаруживается первым (т.е. при GrdF_First) - все нормально, однако если он обнаруживается вторым (т.е. при GrdF_Next) – то для него при проверке подписи всегда будет ошибка 67 = Invalid digital sign.
Все выглядит так, что как будто после вызова GrdLogout, последующий вызов GrdLogin подключает не к тому ключу, который был найден GrdFind.

Re: Guardant API (SDK 7 Update6) для Delphi - проверка цифровой подписи

Здравствуйте.

victordr пишет:

т.е. у них разные и открытый и закрытый ключ ECC160 для алгоритма цифровой подписки

Пока все выглядит так, как будто подпись вы пытаетесь проверять всегда при помощи только одного открытого ключа, который подходит лишь для единственного электронного ключа.

Обратите внимание на что передается указатель в параметре pPublicKey при вызове GrdVerifySign.

Re: Guardant API (SDK 7 Update6) для Delphi - проверка цифровой подписи

Спасибо за быстрый ответ.
Да, я пытаюсь проверять, что вставлен нужный USB-донгл, только при помощи одного открытого ключа. Я использую GrdSign для аппаратного подписывания и GrdVerifySignSource (но не GrdVerifySign) для софтверной проверки.
Указатель в GrdVerifySignSource я проверил - он показывает на правильный элемент в массиве байт USES_ECC_PUBLIC_KEY. Если же указатель показывает "не туда", то в случае, когда подключен единственный "правильный" USB-донгл, получается ошибка 67, как и должно быть.
Может быть, между GrdLogout и GrdFind(hGrd, GrdF_Next, @dwID, @GrdFindInfo) необходимо вставить вызов еще какой-то функции API?

Re: Guardant API (SDK 7 Update6) для Delphi - проверка цифровой подписи

victordr пишет:

Имеются 2 локальных USB-ключа Guardant Code, отличающиеся друг от друга только ключами ECC160

Если нет других атрибутов, по которым можно эти ключи различать (например, разные значения в одном или нескольких полях общего назначения), то гарантировать что приложение с первого раза залогинится к нужному ключу нельзя.

victordr пишет:

Может быть, между GrdLogout и GrdFind(hGrd, GrdF_Next, @dwID, @GrdFindInfo) необходимо вставить вызов еще какой-то функции API?

Можно организовать перебор ключей по ID при помощи GrdSetFindMode.
Т.е. первый вызов GrdFind в цикле позволяет сформировать список всех обнаруженных ключей со значениями их ID (pdwID) → дальше выставляется нужный флаг dwFlags и перый ID из списка передается как параметр dwID для GrdSetFindMode → вызов GrdSetFindMode → вызов GrdLogin → ... → проверка подписи.

Если подпись проверку не прошла, то проделывается все то же самое для второго ID из списка.

Re: Guardant API (SDK 7 Update6) для Delphi - проверка цифровой подписи

Благодарю за совет.
Правильно ли я Вас понял, что GrdLogin использует dwID ключа, заданный при помощи GrdSetFindMode и никак иначе, т.е. что GrdLogin игнорирует результат выполнения GrdFind?

Re: Guardant API (SDK 7 Update6) для Delphi - проверка цифровой подписи

Спасибо, вопрос решен: сделал все по предложенному Вами алгоритму: после составления списка доступных ID всех подключенных USB-донглов, в цикле вызываю  GrdSetFindMode с установленным GrdFM_ID для флагов и очередным ID - в результате очередной вызов GrdLogin обеспечивает подключение к очередному донглу, что и требовалось.
И как я с опозданием обнаружил, этот алгоритм предлагается в описании API функции GrdLogin в разделе документации на Вашем сайте:
https://dev.guardant.ru/display/DOC/GrdLogin

Re: Guardant API (SDK 7 Update6) для Delphi - проверка цифровой подписи

Спасибо за обращение.