Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 2 3 [4] 5   вперед  Ctrl      все
 Re: Как сделать цифровую подпись на основе сертификата  [new]
Miktor
Member

Откуда: г. Хабаровск
Сообщений: 398
Дык я вроде сразу предлагал :) (найду где продаются ВебМани обязательно отблагодарю)
С датами все получилось. Спасибо. Последние 2 маленьких вопроса: Как получить имя серт. центра и владельца сертификата?
12 май 08, 03:28    [5648723]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
renaton
Member

Откуда:
Сообщений: 753
Miktor
Дык я вроде сразу предлагал :) (найду где продаются ВебМани обязательно отблагодарю)
С датами все получилось. Спасибо. Последние 2 маленьких вопроса: Как получить имя серт. центра и владельца сертификата?


не сможешь поделицца исходниками?
12 май 08, 09:17    [5648892]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
Альт
Member

Откуда: Сибирь
Сообщений: 4581
Miktor, упрощенно вот так...
procedure BinToHexInverted( Buffer, Text: PChar; BufSize: Integer);
const
  Convert : Array [ 0..15 ] of Char = '0123456789abcdef';
var
  ii : Integer;
begin
  for ii := BufSize - 1 downto 0 do
  begin
    Text[ 0 ] := Convert[ Byte( Buffer[ ii ]) shr 4 ];
    Text[ 1 ] := Convert[ Byte( Buffer[ ii ]) and $F ];
    Inc( Text, 2 );
  end;
end;

function DecodeSerialNumber( Source : PCRYPT_INTEGER_BLOB ) : String;
begin
  SetLength( Result, Source.cbData * 2 );
  BinToHexInverted( PChar( Source.pbData ), Pointer( Result ), Source.cbData );
end;

function DecodeName( Source : PCRYPTOAPI_BLOB ) : String;
var iLength : DWORD;
begin
  iLength := CertNameToStr( MY_ENCODING_TYPE,
                            PCERT_NAME_BLOB( Source ),
                            CERT_OID_NAME_STR,
                            nil, 0 );
  SetLength( Result, iLength );
  iLength := CertNameToStr( MY_ENCODING_TYPE,
                            PCERT_NAME_BLOB( Source ),
                            CERT_OID_NAME_STR,
                            Pointer( Result ), iLength );
  SetLength( Result, iLength );
end;

ну и примеры вызовов...
  ...
  DecodeName( @Certificate.pCertInfo.Subject )
  DecodeName( @Certificate.pCertInfo.Issuer )
  DecodeSerialNumber( @Certificate.pCertInfo.SerialNumber )
  ...

Поиграйтесь с dwStrType у CertNameToStr и определитесь, что именно вам необходимо из данных, возможно хватит и флага CERT_SIMPLE_NAME_STR
Если капать дальше, то OIDs описаны в разделе Name Properties в Platform SDK, до кучи типы X500 частично описаны таблицей в описании функции CertStrToName
12 май 08, 13:30    [5650465]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
Альт
Member

Откуда: Сибирь
Сообщений: 4581
renaton
не сможешь поделицца исходниками?

любой каприз за ваши деньги... все равно я напишу быстрее, чем вы сумеете понять суть )
12 май 08, 13:32    [5650474]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
renaton
Member

Откуда:
Сообщений: 753
А где достать правильный файл CryptoAPI.pas ???
12 май 08, 15:00    [5651110]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
Альт
Member

Откуда: Сибирь
Сообщений: 4581
renaton
А где достать правильный файл CryptoAPI.pas ???

Уже обсуждалось начиная от.
Для полноценной работы так же необходимы оригинальный WinCrypt.h (7z) (zip) и MS Platform SDK... чем выше версии, тем лучше
12 май 08, 21:43    [5653064]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
renaton
Member

Откуда:
Сообщений: 753
Как сделать так чтобы в свойствах подписаннго файла появилась вкладка подписи и там уже показывались подписанные сертификаты????
14 май 08, 07:54    [5659057]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
Альт
Member

Откуда: Сибирь
Сообщений: 4581
renaton
Как сделать так чтобы в свойствах подписаннго файла появилась вкладка подписи и там уже показывались подписанные сертификаты????

Добрый день. Я не понял вопроса. Почти все обсуждение мы говорим об "присоединенной" подписи. Я уже озвучивал, что она по своей сути является хранилищем сертификатов. "показывались подписанные сертификаты" наверное имелось ввиду сертификаты подписавших... в примерах формировали подпись в файле test.sig, чтобы винда корректно открывала подпись в снапине... ".sig" можно заменить на одно из зарегистрированных расширений, к примеру так test.p7s.
Или мы про программную реализацию... тогда вот так (я немного поменял обвязку кода, который уже приводил ранее в калбек функции GetSignerCertificate):

var
  Store : HCERTSTORE;
  Blob : CRYPTOAPI_BLOB;
  pStream : TMemoryStream;
  Certificate : PCCERT_CONTEXT;
begin
  pStream := TMemoryStream.Create;
  try
    Stream.LoadFromFile( 'c:\test.sig' );
    Blob.cbData := pStream.Size;
    Blob.pbData := pStream.Memory;
    Store := CertOpenStore( CERT_STORE_PROV_PKCS7, MY_ENCODING_TYPE, 0, 0, @Blob );
    if not Assigned( Store ) then
      Err( 'Не удалось открыть хранилище' );
    Certificate := nil;
    repeat
      Certificate := CertEnumCertificatesInStore( Store, Certificate );
      if Assigned( Certificate ) then
      begin
        { тут можно делать с контекстом серитфиката все, что вашей душе угодно }
      end;
    until not assigned( Certificate );
    if ( not CertCloseStore( Store, CERT_CLOSE_STORE_CHECK_FLAG )) then
      Err( 'Ошибка закрытия хранилища' );
  finally
    FreeAndNil( pStream );
  end;

тут уже нет никакой валидации подписи и она просто рассматривается как хранилище

К сообщению приложен файл. Размер - 0Kb
14 май 08, 09:33    [5659244]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
renaton
Member

Откуда:
Сообщений: 753
Так может вот этот скриншот пояснит мой вопрос, это свойтсва инсталлятора АдобеРидер 8

К сообщению приложен файл. Размер - 0Kb
14 май 08, 09:40    [5659278]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
Альт
Member

Откуда: Сибирь
Сообщений: 4581
renaton
Так может вот этот скриншот пояснит мой вопрос, это свойтсва инсталлятора АдобеРидер 8


Зачем вы оверкворите.. неудобно же читать. То, что вы хотите... к теме топика не относится - это authenticode signature. Выполняется утилитами идущими в поставке почти всех девелоперских продуктов мс... подпись в лоб в использованием мастера и сертификата, который я выкладывал для примера тут ранее (у сертификата должна быть включена KU = Code sign или область использования неограниченна), с ком.строки запускаю:
signtool.exe signwizard
по завершению работы мастера, ответив на вопросы и указав файл и сертификат для подписи получаем

К сообщению приложен файл. Размер - 0Kb
14 май 08, 10:27    [5659576]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
renaton
Member

Откуда:
Сообщений: 753
Альт
renaton
Так может вот этот скриншот пояснит мой вопрос, это свойтсва инсталлятора АдобеРидер 8


Зачем вы оверкворите.. неудобно же читать. То, что вы хотите... к теме топика не относится - это authenticode signature. Выполняется утилитами идущими в поставке почти всех девелоперских продуктов мс... подпись в лоб в использованием мастера и сертификата, который я выкладывал для примера тут ранее (у сертификата должна быть включена KU = Code sign или область использования неограниченна), с ком.строки запускаю:
signtool.exe signwizard
по завершению работы мастера, ответив на вопросы и указав файл и сертификат для подписи получаем


А где достать signtool.exe? В поставке делфи он есть?
14 май 08, 10:44    [5659707]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
Альт
Member

Откуда: Сибирь
Сообщений: 4581
renaton
А где достать signtool.exe? В поставке делфи он есть?

Ну, имя тоже может отличаться (например signcode.exe)... не знаю про дельфи... потому утверждать не буду. Список, куда конкретно включены SignTool ищите в msdn, глянул каталоги... у меня на девелоперской машине они продублированы в куче мест... Microsoft SDK/Microsoft.NET 1.1/Microsoft.NET 2.0 и т.д.
поколупайтесь в bin каталогах эмсишных продуктов... первое же найденное:
C:\Program Files\Microsoft.NET\SDK\v1.1\Bin\signcode.exe
14 май 08, 10:58    [5659849]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
LimonFX
Member

Откуда:
Сообщений: 77
vovanka
ты прогу домучал?

Прогу домучал. Вроде всё работает.
Если есть вопросы то чем смогу, помогу. Но это было так давно, что я уже успел немного позабыть и уволится из того банка в котором писал эту программку, не знаю какова её судьба, но для себя исходнички успел скопировать :)
24 июн 08, 12:28    [5839208]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
vovanka
Member

Откуда:
Сообщений: 11
дай почитать пожалуста, для само образования:))
30 июл 08, 09:56    [6002585]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
_test_
Member

Откуда: Узбекистан, Навои -> Сибирь, Томск -> Санкт-Петербург
Сообщений: 45
LimonFX
C предыдущим вопросом я уже разобрался - сертификат находит.


Ребят, такая же проблема. выложил вопрос здесь:

http://programmersforum.ru/showthread.php?t=47254

http://www.cyberforum.ru/win-api/thread31754.html

http://forum.vingrad.ru/forum/topic-257177/kw-certfindcertificatei-%D1%81%D0%B5%D1%80%D1%82%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%82.html

http://www.cryptopro.ru/cryptopro/forum2/default.aspx?g=posts&t=1319

ПОМОГИТЕ ПОЖАЛУЙСТА!
27 апр 09, 16:41    [7119402]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
Альт
Member

Откуда: Сибирь
Сообщений: 4581
О... Томск... единственный, известный мне город, где есть маршрутка двигающаяся со Спичечной фабрики на Карандашную ) один из самых любимых городов ) еще неделю назад я бы помог разобраться... сидя в том же лагерном... без всяких проблем )
Вопрос сишный и это первое... CertOpenStore без "MY_ENCODING_TYPE" и с закомментированным enc.type... на глаз мало чего ловится... покажите сертификат
27 апр 09, 20:11    [7120429]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
Альт
Member

Откуда: Сибирь
Сообщений: 4581
Как-то я вчера больше о Томске мечтал... чем на код смотрел )
В общем, нормальный код... насколько он может быть нормальным для си )... соорудил пробник (в приложении сертификат с RDN CN='Gafarov_Artur') и запихнул его в личные... проверяю кодом:
+
const
  CN = 'Gafarov_Artur';
  CERT_STORE_NAME = 'MY';
  CRYPTO_ENCODING_TYPE : DWORD = PKCS_7_ASN_ENCODING or X509_ASN_ENCODING;
var
  hStore : HCERTSTORE;
  pCert : PCCERT_CONTEXT;
begin
  hStore := CertOpenSystemStore( 0, CERT_STORE_NAME );
  if CryptoCheck( hStore <> 0 ) then
  try
    pCert := CertFindCertificateInStore( hStore, CRYPTO_ENCODING_TYPE, 0,
      CERT_FIND_SUBJECT_STR, CN, nil );
    if CryptoCheck( Assigned( pCert )) then
    try
    //
    // Работаем с сертификатом
    //
    finally
      CryptoCheck( CertFreeCertificateContext( pCert ));
    end;
  finally
    CryptoCheck( CertCloseStore( hStore, CERT_CLOSE_STORE_CHECK_FLAG ));
  end;
end;

все работает, все находит... попробуйте моим вариантом, через CertOpenSystemStore и моим же сертификатом.
зы: есть еще мысли про printableString в вашем RDN и допустимых символов в значении ('_' не входит в их число), но тут надо видеть ваш сертификат. Чем вы его сооружали?

К сообщению приложен файл (ga.p7b - 1Kb) cкачать
28 апр 09, 09:06    [7121317]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: Как сделать цифровую подпись на основе сертификата  [new]
LimonFX
Member

Откуда:
Сообщений: 77
О! Моя первая тема на sql.ru :) Помню тогда сильно погрузился в эту задачу, недели на две. Очень помогли примеры на msdn'e. Там правда код на Си, но на delphi с легкостью можно самому переписать.
7 май 10, 15:19    [8742865]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
frozzen
Member

Откуда:
Сообщений: 35
Альт, спасибо!
коды в теме полезные
9 июн 10, 14:58    [8916259]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
_Сыр_
Guest
Да... Ребята... Тема интересная... Жаль что я ее смотрю ))
Подскажите с чего начать?.. Допустим какие компоненты должны быть на 12 дельфе, библиотеки?
7 сен 10, 17:22    [9399288]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
one123456
Guest
Люди, подскажите, как получить данные о сертификате, который находится в контейнере. Ну или ссыли, чет я уже совсем подзадолбался.
8 сен 10, 12:58    [9403528]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
Гвость
Guest
Дабы не плодить тему...

Нужно подписать сертификатом файл.

Мой код:

procedure TForm1.btnSignClick(Sender: TObject);
Const
  CERT_STORE_NAME = 'MY';
  MY_ENCODING_TYPE = PKCS_7_ASN_ENCODING or X509_ASN_ENCODING;
var
  wsFind : WideString;
  CertStore: HCERTSTORE;
  Cert:  PCERT_CONTEXT;

  SigParams: CRYPT_SIGN_MESSAGE_PARA;

  strMessage: String;
  strSize: DWORD;

  SignedBlob: CRYPT_DATA_BLOB;
  SignedSize: DWORD;
begin
  //Хранилище
  CertStore := CertOpenSystemStore( 0, 'MY');
  if CertStore = nil then exit;

  //Сертификат
  wsFind := 'ТЕСТ';
  Cert := CertFindCertificateInStore(CertStore, PKCS_7_ASN_ENCODING or X509_ASN_ENCODING,
  0, CERT_FIND_SUBJECT_STR, PWideString(wsFind), nil);
  if Cert = nil then exit;

  //Данные которые подписываем
  strMessage := '123';
  strSize := 3;

      SigParams.cbSize := SizeOF(CRYPT_SIGN_MESSAGE_PARA);
      SigParams.dwMsgEncodingType := MY_ENCODING_TYPE;
      SigParams.pSigningCert := Cert;
      SigParams.HashAlgorithm.pszObjId := szOID_PKCS_7;
      SigParams.HashAlgorithm.Parameters.cbData := 0;
      SigParams.cMsgCert := 1;
      SigParams.rgpMsgCert := @Cert;
      SigParams.cAuthAttr := 0;
      SigParams.dwInnerContentType := 0;
      SigParams.cMsgCrl := 0;
      SigParams.cUnauthAttr := 0;
      SigParams.dwFlags := 0;
      SigParams.pvHashAuxInfo := nil;
      SigParams.rgAuthAttr := nil;

      SignedBlob.pbData := nil;

      if CryptSignMessage(@SigParams, False, 1, @strMessage, @strSize, SignedBlob.pbData, SignedBlob.cbData) then
        begin
          Memo1.Lines.Add('Размер: ' + intToStr(SignedBlob.cbData));
        end
      else Memo1.Lines.Add('False');

      FreeAndNil(SigParams);

      CertFreeCertificateContext(Cert);
      CertCloseStore(CertStore, CERT_CLOSE_STORE_CHECK_FLAG );
end;

Размер возвращается но после этого пол секунды спустя Эксес Виолешн... Если запускать не из Delphi прога просто закрывается...

для работы с cryptoAPI использую JwaWinCrypt.pas от JEDI

function CryptSignMessage(pSignPara: PCRYPT_SIGN_MESSAGE_PARA;
  fDetachedSignature: BOOL; cToBeSigned: DWORD; rgpbToBeSigned: LPBYTE;
  rgcbToBeSigned: LPDWORD; var pbSignedBlob: LPBYTE; var pcbSignedBlob: DWORD): BOOL; stdcall;
19 окт 10, 12:12    [9632811]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
Альт
Member

Откуда: Сибирь
Сообщений: 4581
Не спешите меня хоронить, я тут регулярно появлюсь.

Тут надо просто немного думать.
SigParams.HashAlgorithm.pszObjId := szOID_PKCS_7;
основа подписи - это хеш к данным (вычисленный по какому-то известному аглоритму), который на втором шаге шифруется приватным ключом пары. Разные провайдеры поддерживают разные наборы алгоритмов хеширования. Вот этой строчкой и задается алгоритм хеша. Перечитайте топик, ведь это обсуждалось c LimonFX еще в 2007 году.

FreeAndNil(SigParams);
SigParams - это структура, а не объект и этот код никогда не откомпилируется. И SignedBlob тоже структура. Их элементарно надо занулить перед использованием. Как-то вот так.
FillChar(SigParams, SizeOf(SigParams), 0);
FillChar(SignedBlob, SizeOf(SignedBlob), 0);
Можно смело воткнуть в самое начало функции.
Да и телепаты подсказывают, что у вас в SignedBlob мусор. Вызов CryptSignMessage должен быть двойным. На первом вы запрашиваете размер подписи, потом выделяете память, и лишь на повторном вызове получаете заветную подпись. Профит.
21 окт 10, 09:38    [9646306]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
Гвость
Guest
Здравствуйте, Альт.

Сейчас если ставлю перед вызовом CryptSignMessage ваш код:
FillChar(SignedBlob, SizeOf(SignedBlob), 0);

или

SignedBlob.cbData := 0;

функция возвращает False. Но при этом приложение не падает.

Если перед вызовом CryptSignMessage не ставить вышеприведённый код. То при первом вызове функция возвращает размер:
Memo1.Lines.Add('Размер: ' + intToStr(SignedBlob.cbData));

но сразу после вылетает...

с алгоритмом хеширования понятно:
SigParams.HashAlgorithm.pszObjId := szOID_RSA_SHA1RSA;

теперь так... посмотрел в сертификате "алгоритм подписи".
21 окт 10, 13:34    [9648858]     Ответить | Цитировать Сообщить модератору
 Re: Как сделать цифровую подпись на основе сертификата  [new]
Гвость
Guest
GetLastError даёт 5... ERROR_ACCESS_DENIED
21 окт 10, 15:51    [9650586]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 2 3 [4] 5   вперед  Ctrl      все
Все форумы / Delphi Ответить