Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Наши способы организации безопасного удалённого доступа к рабочим местам и корпоративным ресурсам
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Рогнар Рыжий  
#1 Оставлено : 17 июня 2019 г. 4:21:57(UTC)
Рогнар Рыжий

Статус: Новичок

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

Сказал(а) «Спасибо»: 5 раз
Здравствуйте, мне необходимо достать данные (фамилию,имя,отчество) из сертификата X509Certificate Base64Binary идей вообще ни каких нет, с электронной подписью не приходилось работать. Вот пример программы где я пытаюсь достать данные из подписанного файла и расшифровать, схема подписи и файл с подписью xmldsig-core-schema.rar (3kb) загружен 4 раз(а). a59cbb3e-c23d-4dd6-9706-0ff79169204d.rar (4kb) загружен 5 раз(а). dostat' sertifikat.rar (4kb) загружен 8 раз(а).
Offline Андрей Писарев  
#2 Оставлено : 17 июня 2019 г. 9:39:43(UTC)
Андрей *

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

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

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



Эта конференция требует регистрации перед тем как вы сможете увидеть скрытые сообщения.

Техническую поддержку оказываем тут
Наша база знаний
thanks 12 пользователей поблагодарили Андрей * за этот пост.
two_oceans оставлено 17.06.2019(UTC), Малакшинов Евгений оставлено 17.07.2019(UTC), prog_mail оставлено 01.10.2019(UTC), haword оставлено 12.11.2019(UTC), delem оставлено 21.11.2019(UTC), filial-foton оставлено 29.11.2019(UTC), vitalislep оставлено 19.12.2019(UTC), LONG11 оставлено 12.04.2020(UTC), Alex Zenon оставлено 15.04.2020(UTC), quartz оставлено 24.06.2020(UTC), olega69 оставлено 08.07.2020(UTC), eisy оставлено 09.07.2020(UTC)
Offline Андрей Писарев  
#3 Оставлено : 17 июня 2019 г. 9:53:14(UTC)
Андрей *

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

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

Сказал «Спасибо»: 342 раз
Поблагодарили: 1347 раз в 1046 постах
в SUBJECT будет для указанного xml:

Цитата:
ОГРН=1044205104580, ИНН=004205077509, СНИЛС=03816119646, STREET="ул. Волгоградская, д.23-А", SN=Карягин, G=Вячеслав Викторович, C=RU, L=Кемерово, S=42 - Кемеровская область, E=Gbmse42@fbmse.ru, O="ФКУ ""ГБ МСЭ по Кемеровской области"" Минтруда России", OU=Бюро 5, T=Руководитель бюро, CN="ФКУ ""ГБ МСЭ по Кемеровской области"" Минтруда России"



Либо модифицировать:

Цитата:
// SN = 2.5.4.4 Surname Фамилия
// G = 2.5.4.42 givenName Имя + Отчество

Surname := GetInfo(CERT_NAME_ATTR_TYPE, 0, PAnsiChar('2.5.4.4'));
givenName:= GetInfo(CERT_NAME_ATTR_TYPE, 0,PAnsiChar( '2.5.4.42'));



Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Андрей * за этот пост.
Рогнар Рыжий оставлено 18.06.2019(UTC)
Offline Андрей Писарев  
#4 Оставлено : 17 июня 2019 г. 9:56:15(UTC)
Андрей *

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

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

Сказал «Спасибо»: 342 раз
Поблагодарили: 1347 раз в 1046 постах
Поиск лучше делать по объектным идентификаторам (OID), чем парсить строку на разные вариации подстроки
(ИНН\INN = 1.2.643.3.131.1.1 , ОГРН\OGRN = 1.2.643.100.1 и т.п.)

Snimok ehkrana ot 2019-06-17 10-53-54.png (36kb) загружен 32 раз(а).

Техническую поддержку оказываем тут
Наша база знаний
Offline Рогнар Рыжий  
#5 Оставлено : 17 июня 2019 г. 9:59:01(UTC)
Рогнар Рыжий

Статус: Новичок

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

Сказал(а) «Спасибо»: 5 раз
Автор: Андрей Писарев Перейти к цитате
Поиск лучше делать по объектным идентификаторам (OID), чем парсить строку на разные вариации подстроки
(ИНН\INN = 1.2.643.3.131.1.1 , ОГРН\OGRN = 1.2.643.100.1 и т.п.)

Snimok ehkrana ot 2019-06-17 10-53-54.png (36kb) загружен 32 раз(а).



Дело в том что я не знаю как это реализовать в Delphi 7

Offline Андрей Писарев  
#6 Оставлено : 17 июня 2019 г. 10:00:48(UTC)
Андрей *

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

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

Сказал «Спасибо»: 342 раз
Поблагодарили: 1347 раз в 1046 постах
Автор: Рогнар Рыжий Перейти к цитате


Дело в том что я не знаю как это реализовать в Delphi 7



В первом от меня сообщении готовый код, что мешает скачать необходимое для работы с CryptoAPI,
указанное в uses и добавить в свой unit необходимое?
Техническую поддержку оказываем тут
Наша база знаний
Offline Рогнар Рыжий  
#7 Оставлено : 17 июня 2019 г. 10:22:43(UTC)
Рогнар Рыжий

Статус: Новичок

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

Сказал(а) «Спасибо»: 5 раз
Автор: Андрей Писарев Перейти к цитате

В первом от меня сообщении готовый код, что мешает скачать необходимое для работы с CryptoAPI,
указанное в uses и добавить в свой unit необходимое?


Вы имеете ввиду Wcrypt2.pas

Offline Андрей Писарев  
#8 Оставлено : 17 июня 2019 г. 10:35:02(UTC)
Андрей *

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

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

Сказал «Спасибо»: 342 раз
Поблагодарили: 1347 раз в 1046 постах
Автор: Рогнар Рыжий Перейти к цитате

Вы имеете ввиду Wcrypt2.pas


Можно и его.

Техническую поддержку оказываем тут
Наша база знаний
Offline Рогнар Рыжий  
#9 Оставлено : 17 июня 2019 г. 10:59:57(UTC)
Рогнар Рыжий

Статус: Новичок

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

Сказал(а) «Спасибо»: 5 раз
Автор: Андрей Писарев Перейти к цитате

В первом от меня сообщении готовый код, что мешает скачать необходимое для работы с CryptoAPI,
указанное в uses и добавить в свой unit необходимое?


Можете посоветовать что можно почитать или где поискать как работать с CryptoAPI или где посмотреть примеры как работать, или поподробней объяснить что нужно написать в моем unit.

Отредактировано пользователем 17 июня 2019 г. 11:02:22(UTC)  | Причина: Не указана

Offline two_oceans  
#10 Оставлено : 17 июня 2019 г. 12:45:05(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 63 раз
Поблагодарили: 228 раз в 214 постах
Автор: Рогнар Рыжий Перейти к цитате
Вы имеете ввиду Wcrypt2.pas
Не не не... это вредный совет, так как этот модуль очень старый, тем более из комплекта дельфи 7, многие функции/константы просто не будут работать, особенно если писать 64-разрядное приложение. Лучше скачать jwawincrypt, например, у меня 1.17 2007/09/05, там хотя бы несложно допилить описание типов хэндлов до 64 битных. Там же есть комментарии на английском к каждой функции, еще можно почитать MSDN игнорируя, что функции по мнению Майкрософт устарели и будут удалены в будущих версиях виндоуз.

Как бы для сертификата даже особо и криптографии не надо, достаточно только нескольких функций. Для получения данных из подписанного файла Вам нужно: 1) выделить нужный текст, содержащий сертификат в Base64 из файла. Это можно сделать либо строковыми функциями либо xml парсерсом и его функциями. Предполагаю, что это Вы уже сделали.

2) декодировать сертификат из Base64, есть огромная куча реализаций для дельфи, но конечно ничто не мешает написать свою. К слову есть и реализация в CryptoAPI StringToBinary, но мне так и не удалось заставить ее работать - вместо декодирования кодирует еще раз, поэтому нашел исходник юнита base64 и скопипастил в свой юнит. Не весь юнит base64 подключил, так как там реализовано в виде объекта и тянулясь длинная объектная цепочка наследования и скомпилированная библиотека распухала в разы.

3) передать сертификат декодированный из base64 certData в
Код:
pCertCont:=CertCreateCertificateContext(X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, PByte(CertData.str), CertData.Len);
У меня для удобства передачи между библиотеками свои строки - запись в которой str адрес буфера строки, Limit длина буфера выделенная, Len занятая длина буфера без конечного символа 0. Возвращается указатель на контекст сертификата, контекст удобен тем, данные закодированные в сертификате автоматически частично раскодированы и их можно уже и вручную выдергивать, но мы же не варвары, есть специальные функции для имени и различных хэшей сертификата.

С другой стороны, вручную удобнее выдергивать серийный номер сертификата, так как в дельфи его надо заодно перевернуть. Перевод номера сертификата в десятичное представление - отдельная тема, так как у стандартных целочисленных типов не хватает длины чтобы вместить скажем 22 или 27 байт серийного номера.

В коде выше конечно отличная альтернатива шагам 4 и 5.

Отредактировано пользователем 17 июня 2019 г. 13:08:05(UTC)  | Причина: Не указана

thanks 1 пользователь поблагодарил two_oceans за этот пост.
Рогнар Рыжий оставлено 18.06.2019(UTC)
Offline Рогнар Рыжий  
#11 Оставлено : 17 июня 2019 г. 12:56:08(UTC)
Рогнар Рыжий

Статус: Новичок

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

Сказал(а) «Спасибо»: 5 раз
Автор: Андрей Писарев Перейти к цитате
Автор: Рогнар Рыжий Перейти к цитате

Вы имеете ввиду Wcrypt2.pas


Можно и его.



Можете также подсказать что вы используете для работы с CryptoAPI
Offline Андрей Писарев  
#12 Оставлено : 17 июня 2019 г. 13:04:14(UTC)
Андрей *

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

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

Сказал «Спасибо»: 342 раз
Поблагодарили: 1347 раз в 1046 постах
Автор: Рогнар Рыжий Перейти к цитате
Автор: Андрей Писарев Перейти к цитате
Автор: Рогнар Рыжий Перейти к цитате

Вы имеете ввиду Wcrypt2.pas


Можно и его.



Можете также подсказать что вы используете для работы с CryptoAPI


jwawincrypt
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Андрей * за этот пост.
Рогнар Рыжий оставлено 18.06.2019(UTC)
Offline Рогнар Рыжий  
#13 Оставлено : 18 июня 2019 г. 9:55:24(UTC)
Рогнар Рыжий

Статус: Новичок

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

Сказал(а) «Спасибо»: 5 раз
Автор: two_oceans Перейти к цитате
Не не не... это вредный совет, так как этот модуль очень старый, тем более из комплекта дельфи 7, многие функции/константы просто не будут работать, особенно если писать 64-разрядное приложение. Лучше скачать jwawincrypt, например, у меня 1.17 2007/09/05, там хотя бы несложно допилить описание типов хэндлов до 64 битных. Там же есть комментарии на английском к каждой функции, еще можно почитать MSDN игнорируя, что функции по мнению Майкрософт устарели и будут удалены в будущих версиях виндоуз.

Как бы для сертификата даже особо и криптографии не надо, достаточно только нескольких функций. Для получения данных из подписанного файла Вам нужно: 1) выделить нужный текст, содержащий сертификат в Base64 из файла. Это можно сделать либо строковыми функциями либо xml парсерсом и его функциями. Предполагаю, что это Вы уже сделали.

2) декодировать сертификат из Base64, есть огромная куча реализаций для дельфи, но конечно ничто не мешает написать свою. К слову есть и реализация в CryptoAPI StringToBinary, но мне так и не удалось заставить ее работать - вместо декодирования кодирует еще раз, поэтому нашел исходник юнита base64 и скопипастил в свой юнит. Не весь юнит base64 подключил, так как там реализовано в виде объекта и тянулясь длинная объектная цепочка наследования и скомпилированная библиотека распухала в разы.

3) передать сертификат декодированный из base64 certData в
Код:
pCertCont:=CertCreateCertificateContext(X509_ASN_ENCODING or PKCS_7_ASN_ENCODING, PByte(CertData.str), CertData.Len);
У меня для удобства передачи между библиотеками свои строки - запись в которой str адрес буфера строки, Limit длина буфера выделенная, Len занятая длина буфера без конечного символа 0. Возвращается указатель на контекст сертификата, контекст удобен тем, данные закодированные в сертификате автоматически частично раскодированы и их можно уже и вручную выдергивать, но мы же не варвары, есть специальные функции для имени и различных хэшей сертификата.

С другой стороны, вручную удобнее выдергивать серийный номер сертификата, так как в дельфи его надо заодно перевернуть. Перевод номера сертификата в десятичное представление - отдельная тема, так как у стандартных целочисленных типов не хватает длины чтобы вместить скажем 22 или 27 байт серийного номера.

В коде выше конечно отличная альтернатива шагам 4 и 5.


Спасибо вроде получилось, я была в отчаянии, вы меня спасли когда сделаю покрасивее скину сюда вдруг кому пригодится

Offline Рогнар Рыжий  
#14 Оставлено : 18 июня 2019 г. 10:20:30(UTC)
Рогнар Рыжий

Статус: Новичок

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

Сказал(а) «Спасибо»: 5 раз
Автор: two_oceans Перейти к цитате

rData:=CertGetNameString(pCertCont, strDisp, StrTp, pTpPara, @(Rez.str^), Rez.Limit);[/code]Можно регулировать представление через strDisp самое

я эту строчку не поняла и сделала так, можете поподробнее объяснить rData какого типа и как можно значение сразу в строковую переменную записать?
Код:
var
  CertName: array[0..255] of Char;
begin
  MTable1.Open;
  if CertGetNameString(pCertCont, CERT_NAME_ATTR_TYPE, 0, PAnsiChar('2.5.4.4'),
    CertName, 256) = 0 then
    RaiseLastWin32Error;
  showmessage( CertName);
  MTable1.Edit;
  MTable1.Append;
  MTable1.FieldByName('fam').AsString:=CertName;
  if CertGetNameString(pCertCont, CERT_NAME_ATTR_TYPE, 0, PAnsiChar( '2.5.4.42'),
    CertName, 256) = 0 then
    RaiseLastWin32Error;
  showmessage( CertName);
  MTable1.FieldByName('imot').AsString:=CertName;
  MTable1.Post;
end;

Отредактировано пользователем 18 июня 2019 г. 10:22:48(UTC)  | Причина: Не указана

Offline two_oceans  
#15 Оставлено : 18 июня 2019 г. 11:45:05(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 63 раз
Поблагодарили: 228 раз в 214 постах
Автор: Рогнар Рыжий Перейти к цитате
Автор: two_oceans Перейти к цитате

Код:
rData:=CertGetNameString(pCertCont, strDisp, StrTp, pTpPara, @(Rez.str^), Rez.Limit);
Можно регулировать представление через strDisp самое

я эту строчку не поняла и сделала так, можете поподробнее объяснить rData какого типа и как можно значение сразу в строковую переменную записать?
Почти правильно сделали - в таком виде Вы не узнаете какая на самом деле длина возвращается в CertName вместо фамилии из 10 символов скопируте все 256 символов. Если строка неинициализирована, то много мусора скопируется. Мелочь конечно, но по вашему коду Вы получается выдаете исключение на сертификаты без ФИО, наряду с ошибками CryptoAPI. rData это как раз та самая длина возвращенного текста, тип 32-битное беззнаковое целое число, у меня дельфисовместимый компилятор, этот тип называется dword или cardinal или ulong.

В обычную строковую записать может быть проблемой, так как по умолчанию string синоним ansistring или longstring, а у них адрес буфера прыгает при любом изменении, что неприемлемо при передаче в WinApi вообще и в CryptoApi в частности. Если длины 255 достаточно, то можно использовать shortstring (там байт длины и фиксированный буфер длиной 255 символов). При этом в пятый параметр передается ссылка на первый символ @s[1] а после вызова нужно не забыть записать s[0]:=chr(rdata and $ff); Если не достаточно 255 байт, то можно попробовать обойтись PChar PAnsiChar PWideChar, там с длиной манипуляций не нужно, но может быть проблема в сложных типах когда Си (на котором пишут в Майкрософт) трактует поле как однозначно указатель (а бывает как указатель на указатель на указатель на данные), а Дельфи то как указатель, то как строку. Все это и сподвигло меня перейти на самописный тип-запись для хранения строк, мороки не то чтобы стало больше, зато точно знаю поведение. Плохо совместимо кодом для ansistring, но так как этот код в основном объекты, а объекты несовместимо перетаскивать между библиотеками, решил что для библиотек самописный тип-запись самое то.

В продолжение вчерашнего вопроса о разных модулях - какой тип указывается в объявлении функции зависит от используемого модуля. У Вас похоже пятый параметр объявлен как var. На дельфи это конечно удобнее, но декларации winapi позволяют в подобные строковые параметры передать nil вместо адреса буфера для запроса длины нужного буфера, а var переменная дельфи не может быть nil, то есть более корректно объявить параметр как указатель или P****Char для всей полноты функционала. У меня модуль с объявлениями как указателями, но строгий тип указателя на буфер не соответствует строгому типу указателя в объявлении PByte или PChar, поэтому в строке-примере сами данные ^ от указателя и снова беру адрес @, тип становится нетипизированным указателем совместимым с любым указателем, это конечно равносильно явному приведению типа, но на приведение мой компилятор выдает notice, а комбинацию разименовывания указателя с взятием адреса считает допустимой.

Отредактировано пользователем 18 июня 2019 г. 12:18:17(UTC)  | Причина: Не указана

Offline Рогнар Рыжий  
#16 Оставлено : 27 июня 2019 г. 10:37:32(UTC)
Рогнар Рыжий

Статус: Новичок

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

Сказал(а) «Спасибо»: 5 раз
Возник еще вопрос не могу найти информацию как достать дату начала и дату окончания сертификата

Offline two_oceans  
#17 Оставлено : 27 июня 2019 г. 11:05:07(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 63 раз
Поблагодарили: 228 раз в 214 постах
Не находится наверно потому что слишком просто. Смотрим структуру CERT_INFO: https://technet.microsof...r/aa377200%28v=vs.110%29
Находим там даты (NotBefore NotAfter палятся просто по типу данных), находим указатель на структуру в контексте сертификата (вроде как есть и специальная функция для получения CERT_INFO, но тут как раз можно "срезать путь" прямым обращением к памяти). Пусть pCertCont это контекст сертификата, тогда получаем что-то вроде (точное написание может отличаться в зависимости от модуля, смотря как модуль назвал поля в записях):
Код:
var DtStart,DtEnd:TFILETIME;

DtStart:=pCertCont^.pCertInfo^.NotBefore;
DtEnd:=pCertCont^.pCertInfo^.NotAfter;
Дальше из TFILETIME переводите в нужный формат. И мне конечно любопытно правда ли Вы будете использовать дату начала?

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

Отредактировано пользователем 27 июня 2019 г. 11:12:31(UTC)  | Причина: Не указана

thanks 1 пользователь поблагодарил two_oceans за этот пост.
Рогнар Рыжий оставлено 27.06.2019(UTC)
Offline Рогнар Рыжий  
#18 Оставлено : 27 июня 2019 г. 11:11:17(UTC)
Рогнар Рыжий

Статус: Новичок

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

Сказал(а) «Спасибо»: 5 раз
Автор: two_oceans Перейти к цитате
Смотрим CERT_INFO: https://technet.microsof...r/aa377200%28v=vs.110%29
Находим там даты, находим указатель на структуру в контексте сертификата. Пусть pCertCont это контекст сертификата, тогда получаем что-то вроде (точное написание может отличаться в зависимости от модуля):
Код:
var DtStart,DtEnd:TFILETIME;

DtStart:=pCertCont^.pCertInfo^.NotBefore;
DtEnd:=pCertCont^.pCertInfo^.NotAfter;
Дальше из TFILETIME переводите в нужный формат.


Ошибку выдает

Incompatible types: 'Windows._FILETIME' and 'JwaWinType._FILETIME'

Offline two_oceans  
#19 Оставлено : 27 июня 2019 г. 11:14:38(UTC)
two_oceans

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

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

Сказал(а) «Спасибо»: 63 раз
Поблагодарили: 228 раз в 214 постах
Поэтому я и выкидываю модуль Windows где могу. И та версия и другая импортированы из одного заголовочного файла Си, но Дельфи их считает разными. Нужно явное приведение типа:
Код:
DtStart:=Windows._FILETIME(pCertCont^.pCertInfo^.NotBefore);
DtEnd:=Windows._FILETIME(pCertCont^.pCertInfo^.NotAfter);

Отредактировано пользователем 27 июня 2019 г. 11:15:59(UTC)  | Причина: Не указана

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