Ключевое слово в защите информации
ключевое слово
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход. Новые регистрации запрещены.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline RybalkoAA  
#1 Оставлено : 24 марта 2021 г. 8:29:47(UTC)
RybalkoAA

Статус: Участник

Группы: Участники
Зарегистрирован: 16.02.2021(UTC)
Сообщений: 21
Российская Федерация
Откуда: Москва

Сказал(а) «Спасибо»: 1 раз
Добрый день.
Почему может быть так, что csptest видит контейнеры на подключенных Рутокен, а наш CryptoApi-код не видит эти контейнеры.
Сам код:
Код:

    AcquireContext(@FCryptProv, nil, CRYPT_VERIFYCONTEXT, '');
    try
      I := 0;

      FEnumFlag := CRYPT_FIRST;

      if FCryptGetProvParam(FCryptProv, PP_ENUMCONTAINERS, nil, @FKeyLenNeed, FEnumFlag) then
      begin
        SetLength(FKeyData, FKeyLenNeed);

        while FCryptGetProvParam(FCryptProv, PP_ENUMCONTAINERS, @FKeyData[1], @FKeyLenNeed, FEnumFlag) do
        begin
          FItem := TCustomCryptoContainerItem.Create;
          FItem.KeyID := PAnsiChar(FKeyData);

          // открытие исходного контейнера ключей
          AcquireContext(@FSourceCryptProv, PWideChar(WideString(FItem.KeyID)), CRYPT_SILENT, '');
          try
            // инициализация параметров алгоритмов
            SetAlgorithmParams(FSourceCryptProv);

            // полный путь к контейнеру
            if FCryptGetProvParam(FSourceCryptProv, PP_UNIQUE_CONTAINER, nil, @FKeyLenNeed, 0) then
            begin
              SetLength(FKeyData, FKeyLenNeed);

              if not FCryptGetProvParam(FSourceCryptProv, PP_UNIQUE_CONTAINER, @FKeyData[1], @FKeyLenNeed, 0) then
                RaiseLastCryptoApiError;

              FItem.ContainerName := UnicodeString(PAnsiChar(FKeyData));
            end;

            CryptoLogMessageFmt(CLM_SEARCH_PUBLIC_KEY, [FItem.KeyID]);

            // проверяем наличие ключей в контейнере
            if FCryptGetUserKey(FSourceCryptProv, AT_KEYEXCHANGE, @FSourceKey) then
            try

              // получение исходного сертификата
              if FCryptGetKeyParam(FSourceKey, KP_CERTIFICATE, nil, @FKeyLenNeed, 0) then
              begin
                SetLength(FKeyData, FKeyLenNeed);

                if not FCryptGetKeyParam(FSourceKey, KP_CERTIFICATE, @FKeyData[1], @FKeyLenNeed, 0) then
                  RaiseLastCryptoApiError;

                FItem.CertData := UnicodeString(EncodePEM(FKeyData, 'BEGIN CERTIFICATE', 'END CERTIFICATE'));

              end;

            finally
              if not FCryptDestroyKey(FSourceKey) then
                RaiseLastCryptoApiError;
            end

          finally
            ReleaseContext(FSourceCryptProv);
          end;

          Result.Add(FItem);

          FEnumFlag := CRYPT_NEXT;
          Inc(I);
        end;
      end;

      CryptoLogMessageFmt(CLM_CONTAINER_LIST, [I]);

    finally
      ReleaseContext(FCryptProv);
    end;
Offline Андрей *  
#2 Оставлено : 24 марта 2021 г. 10:59:14(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 14,181
Мужчина
Российская Федерация

Сказал «Спасибо»: 620 раз
Поблагодарили: 2396 раз в 1885 постах
Здравствуйте.

Нужны подробности...
Что там в AcquireContext и что в примерах ...
сверяли?
Техническую поддержку оказываем тут
Наша база знаний
Offline RybalkoAA  
#3 Оставлено : 24 марта 2021 г. 16:08:40(UTC)
RybalkoAA

Статус: Участник

Группы: Участники
Зарегистрирован: 16.02.2021(UTC)
Сообщений: 21
Российская Федерация
Откуда: Москва

Сказал(а) «Спасибо»: 1 раз
Внутри AcquireContext вызывается:
Код:
CryptAcquireContext(ACryptProv, nil, 'Crypto-Pro GOST R 34.10-2012 Cryptographic Service Provider', 80, CRYPT_VERIFYCONTEXT);
Offline Агафьин Сергей  
#4 Оставлено : 25 марта 2021 г. 11:25:25(UTC)
Grey

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 12.08.2013(UTC)
Сообщений: 834
Мужчина
Российская Федерация
Откуда: Москва

Сказал «Спасибо»: 5 раз
Поблагодарили: 215 раз в 174 постах
Добрый день.
Я бы поставил на ошибку в коде, из-за которой не перечисляется часть контейнеров.
Мне, честно говоря, сложно воспринимать указанный код, поэтому напишу, как правильно:
Код:

len = 0;
CryptGetProvParam(PP_ENUMCONTAINERS, NULL, &len, CRYPT_FIRST);
data = create_buffer(len);
do {
   code = CryptGetProvParam(PP_ENUMCONTAINERS, data, &len, 0);
  // do something with item
} while (code == ERROR_SUCCESS);


В перечислении можно сразу получать уникальные имена контейнеров, если добавить флаг CRYPT_UNIQUE.
С уважением,
Сергей
Техническую поддержку оказываем здесь.
Наша база знаний.
thanks 1 пользователь поблагодарил Grey за этот пост.
Андрей * оставлено 25.03.2021(UTC)
Offline two_oceans  
#5 Оставлено : 25 марта 2021 г. 13:50:58(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 1,602
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 110 раз
Поблагодарили: 397 раз в 367 постах
Добрый день.
1. Это Дельфи? Какой модуль для доступа к CryptoApi используете? jwawincrypt версии посвежее сразу решит много проблем.

2. На первый взгляд подозрительной в коде кажется пустая строка передаваемая в AcquireContext. С некоторых пор реакция криптопровайдера на nil и на пустую строку отличается (как рекомендует Майкрософт) - если копировали старый код и пустая строка идет в криптопровайдер, то это может быть корнем проблемы.

3. Подозрительные махинации с AnsiString и Widestring - очень вероятно, что у Вас в коде испорчено имя контейнера. Не знаю конечно может есть такие функции конвертации, но более похоже на голое имя типа. От того что фактическую анси строку назовете вайд строкой суть данных в памяти не поменяется, а вот корректное определение длины может улететь в пропасть. Есть специальные функции преобразования WideCharToMultiByte и MultiByteToWideChar для которых явно выделяются буферы памяти и потому ошибиться с конвертацией сложнее.

В идеале нужно использовать ту функцию криптопровайдера (с суффиксом A или W, например, CryptAcquireContextA или CryptAcquireContextW), которая совпадает с поддержкой Юникода самой Вашей программой, тогда и преобразования не нужны. Как раз такой выбор версии функции выполняется модулем jwawincrypt при создании псевдонима функции без суффикса (CryptAcquireContext) и вместе с тем можно явно указать суффикс, если автовыбор оказался неудачен. Функция взята к примеру, так как аналогичные версии есть и у многих других функций. Соответственно, передавать криптопровайдеру сможете именно то, что получено от него без всяких махинаций.

Отредактировано пользователем 25 марта 2021 г. 13:56:05(UTC)  | Причина: Не указана

Offline RybalkoAA  
#6 Оставлено : 25 марта 2021 г. 15:41:58(UTC)
RybalkoAA

Статус: Участник

Группы: Участники
Зарегистрирован: 16.02.2021(UTC)
Сообщений: 21
Российская Федерация
Откуда: Москва

Сказал(а) «Спасибо»: 1 раз
Верно, Дельфи.
Используем advapi32.dll, crypt32.dll, cades.dll
Пустая строка обрабатывается внутри AcquireContext, и, если не пустая, тогда уже устанавливается, иначе никаких действий нет.
По поводу преобразований строк - быть может, но проблема в том, что даже пустые (или полупустые) строки не добавляются в финальный результат + ошибок именно каких-то конвертаций не встречено, просто нет нужных контейнеров.

Отредактировано пользователем 25 марта 2021 г. 15:42:31(UTC)  | Причина: Не указана

Offline Андрей *  
#7 Оставлено : 25 марта 2021 г. 18:27:07(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 14,181
Мужчина
Российская Федерация

Сказал «Спасибо»: 620 раз
Поблагодарили: 2396 раз в 1885 постах
Цитата:
CRYPT_FILTER_PROVIDER_TYPE = $100; //Флаг, позволяющий при перечислении выбирать только контейнеры с ключами, совпадающими с типом криптопровайдера.


// CRYPT_FIRST or CRYPT_UNIQUE or CRYPT_FILTER_PROVIDER_TYPE


p.s. а для 'Aktiv ruToken CSP v1.0' видит?
Техническую поддержку оказываем тут
Наша база знаний
Offline two_oceans  
#8 Оставлено : 26 марта 2021 г. 6:02:02(UTC)
two_oceans

Статус: Эксперт

Группы: Участники
Зарегистрирован: 05.03.2015(UTC)
Сообщений: 1,602
Российская Федерация
Откуда: Иркутская область

Сказал(а) «Спасибо»: 110 раз
Поблагодарили: 397 раз в 367 постах
Автор: RybalkoAA Перейти к цитате
По поводу преобразований строк - быть может, но проблема в том, что даже пустые (или полупустые) строки не добавляются в финальный результат + ошибок именно каких-то конвертаций не встречено, просто нет нужных контейнеров.
Результат просто пустой? Что если Result.Add(FItem); вставить после 15 строки (после FItem.KeyID := PAnsiChar(FKeyData);) - хоть что-то находит? Если да, то перечисление работает и преобразования строк под подозрением, если нет, то AcquireContext возможно не отработал или некорректный буфер в FCryptGetProvParam. В плане буфера интересно какого типа FKeyData.
Автор: RybalkoAA Перейти к цитате
Пустая строка обрабатывается внутри AcquireContext, и, если не пустая, тогда уже устанавливается, иначе никаких действий нет.
В случае VERIFY_CONTEXT как раз действие должно быть когда имя контейнера не указано (то есть nil). Объяснение что-то не сходится с вызовами в коде: первый параметр Вашей функции AcquireContext указатель на переменную типа HCRYPTPROV, во второй передаете имя контейнера, в третий передаете флаг, тогда что за четвертый параметр куда идет пустая строка? При пустой строке в 4 параметре - действий нет?


RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.