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

Откуда: 74
Сообщений: 108
Shuraken,

Видимо вы пропустили первый шаг: TlbExp.exe
4 дек 18, 08:03    [21752561]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
maratvg,

Нет, не забыл, там тоже ошибка
TlbExp : error TX0000 : Невозможно загрузить файл или сборку "file:///C:\FSSRF\A
RM_FSS\gostcryptography.dll" или один из зависимых от них компонентов. Сборка со
здана в более поздней версии среды выполнения чем текущая, и не может быть загру
жена.
4 дек 18, 12:43    [21752796]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
maratvg
Member

Откуда: 74
Сообщений: 108
Shuraken,

Нужно версию SDK более свежую

+
D:\GostCryptography>ft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\TlbExp.exe" D:\GostCryptography\GostCryptography.dll
Microsoft (R) .NET Framework Assembly to Type Library Converter 4.6.1055.0
Copyright (C) Microsoft Corporation. All rights reserved.

Assembly exported to 'D:\GostCryptography\GostCryptography.tlb'

D:\GostCryptography>rogram Files\Microsoft SDKs\Windows\v7.1\Bin\TlbExp.exe" D:\GostCryptography\GostCryptography.dll
Microsoft (R) .NET Framework Assembly to Type Library Converter 3.5.30729.1
Copyright (C) Microsoft Corporation. All rights reserved.

TlbExp : error TX0000 : Невозможно загрузить файл или сборку "file:///D:\GostCryptography\GostCryptography.dll" или один
из зависимых от них компонентов. Сборка создана в более поздней версии среды выполнения чем текущая, и не может быть за
гружена.
4 дек 18, 14:45    [21752991]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
maratvg,

Огромное спасибо, установил.
4 дек 18, 15:26    [21753093]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
maratvg,

правда, там описание функционала отличается от того, что написали Вы. Можете объяснить назначение pSenderCertName (function encryptMsg(const pProvName: WideString; const pCertName: WideString;
const pSenderCertName: WideString; const pSOAPMsg: WideString): WideString;)?
На всякий случай прилагаю архив с моим сгенерированным pas-файлом.

К сообщению приложен файл (GostCryptography.rar - 12Kb) cкачать
4 дек 18, 17:15    [21753412]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
С этим разобрался - взял GostCryptography из папки FssTools, а не ARM_FSS. Правда, теперь там другая проблема: сообщение "Операция не может быть выполнена с текущим ключом", после чего слетают все настройки хранилища сертификатов и приходится перезагружать компьютер. Так что всё весело.
5 дек 18, 11:55    [21754098]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
maratvg
Member

Откуда: 74
Сообщений: 108
Shuraken,

Работал только со старой длл-кой, сейчас нет надобности, поэтому что там поменялось не слежу.
5 дек 18, 14:35    [21754421]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
sql2012
Member

Откуда: РФ
Сообщений: 660
Shuraken
С этим разобрался - взял GostCryptography из папки FssTools, а не ARM_FSS. Правда, теперь там другая проблема: сообщение "Операция не может быть выполнена с текущим ключом", после чего слетают все настройки хранилища сертификатов и приходится перезагружать компьютер. Так что всё весело.


Через CSP контейнер (по сертификату) тестируется без проблем?
5 дек 18, 19:35    [21754872]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
sql2012,

в смысле, нормально ли подписывается и принимается ФСС? Да, там всё нормально, но реализовано не через GostCryptography.
6 дек 18, 10:07    [21755402]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
Очередные грабли с ЭЛН по ФСС. На сей раз шифрование.
Подписанные запросы на получение и отправку данных без проблем обрабатываются тестовым сервером ФСС. Работаю над шифрованием. Вот с ним и возникла проблема.
За основу взял готовый код tkolomiets Электронный больничный ЭЛН. Допилил его под Делфи 7, на которой работаю и стал пробовать шифровать и отсылать на тестовый сервер ФСС. В результате всё время возникает ошибка

ru.ibs.cryptoprto.jcp.wrapper.eln.ws.client.generated.CryptoException_Exception: Не удалось расшифровать сообщение. Возможно сообщение зашифровано на ключе отличном от ключа уполномоченного лица ФСС. Проверьте правильность и актуальность ключа уполномоченного лица ФСС.

С сертификатами всё в порядке, с криптопровайдером тоже. В чём ошибка, понять не могу. В аттаче образец подписанного сообщения, зашифрованного и код. Буду признателен, если посмотрите и укажете на проблему.

С уважением, Александр.

К сообщению приложен файл (EncryptSignMessage.rar - 29Kb) cкачать
18 дек 18, 16:51    [21767394]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
Кто может подсказать аналоги следующих функций для Делфи 7?

TNetEncoding.Base64.EncodeBytesToString
TEncoding.Ansi.GetString
TNetEncoding.Base64.DecodeStringToBytes
TEncoding.Default.GetBytes

А то наткнулся на них в аттаче по подписанию и шифрованию ЭЛН, и не уверен, что правильно подобрал аналоги.
19 дек 18, 20:04    [21768838]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
rgreat
Member

Откуда:
Сообщений: 4899
Shuraken,

К сообщению приложен файл (Base64.pas - 7Kb) cкачать
19 дек 18, 20:14    [21768848]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
alekcvp
Member

Откуда:
Сообщений: 1311
rgreat,

Во-первых, это плохой юнит, уже разбирали.

procedure Base64Encode(const InBuffer; InSize: Cardinal; var OutBuffer); register; overload;
var
  ByThrees, LeftOver: Cardinal;
asm
  mov ESI, [EAX]
  mov EDI, [ECX]
  mov EAX, EBX // <<-- что за значение тут в EBX ?..
  mov ECX, $03
  xor EDX, EDX
  div ECX
  mov ByThrees, EAX 
  ...


Во-вторых, в дельфи есть родной: 2009-XE - EncdDecd.pas, XE2+ - Soap.EncdDecd.pas и ещё вот это.

В-третьих, если родной не нравится можно из какого-нибудь synops'а взять.
19 дек 18, 20:48    [21768884]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
alekcvp
rgreat,

во-вторых, в дельфи есть родной: 2009-XE - EncdDecd.pas, XE2+ - Soap.EncdDecd.pas и ещё вот это.

В-третьих, если родной не нравится можно из какого-нибудь synops'а взять.


Я говорил о Делфи 7. В нём да, есть encddecd, и честно говоря, не совсем понял, как соотнести его
procedure EncodeStream(Input, Output: TStream);
procedure DecodeStream(Input, Output: TStream);
function EncodeString(const Input: string): string;
function DecodeString(const Input: string): string;

с тем, что я написал

TNetEncoding.Base64.EncodeBytesToString
TEncoding.Ansi.GetString
TNetEncoding.Base64.DecodeStringToBytes
TEncoding.Default.GetBytes
19 дек 18, 23:26    [21768991]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
alekcvp
Member

Откуда:
Сообщений: 1311
Shuraken
Я говорил о Делфи 7. В нём да, есть encddecd, и честно говоря, не совсем понял, как соотнести его

TNetEncoding.Base64.EncodeBytesToString
TEncoding.Ansi.GetString
TNetEncoding.Base64.DecodeStringToBytes
TEncoding.Default.GetBytes


Base64:

uses
  EncdDecd;

const
  Data = 'PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8c3RyaW5nPtiq2LPYqjwvc3RyaW5nPg==';

var
  bin: string;

begin
  bin := DecodeString(Data); //  в bin - двоичные данные
  ...

А вот вместо TEncoding, скорее всего, придётся писать свою обёртку над MultiByteToWideChar и WideCharToMultiByte.
20 дек 18, 11:28    [21769279]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
alekcvp
Member

Откуда:
Сообщений: 1311
alekcvp
А вот вместо TEncoding, скорее всего, придётся писать свою обёртку над MultiByteToWideChar и WideCharToMultiByte.

Ну или так (не проверял):
var
  ansi: string;
  def: widestring;
begin
  ansi := 'это кодировка винды (обычно 1251)';
  def := widestring(ansi); // в def теперь unicode
  ...
20 дек 18, 11:33    [21769283]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 3154
Обертки, что бы долго не мучатся (взяты из JCL):

function StringToWideStringEx(const S: ansistring; CodePage: word): WideString;
var
 InputLength, OutputLength: NativeInt;
begin
 InputLength  := Length(S);
 OutputLength := MultiByteToWideChar(CodePage, 0, PAnsiChar(S), InputLength, nil, 0);
 SetLength(Result, OutputLength);
 MultiByteToWideChar(CodePage, 0, PAnsiChar(S), InputLength, PWideChar(Result), OutputLength);
end;

function WideStringToStringEx(const WS: WideString; CodePage: word): ansistring;
var
 InputLength, OutputLength: NativeInt;
begin
 InputLength  := Length(WS);
 OutputLength := WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, nil, 0, nil, nil);
 SetLength(Result, OutputLength);
 WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, PAnsiChar(Result), OutputLength, nil, nil);
end;
20 дек 18, 12:35    [21769369]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
alekcvp
А вот вместо TEncoding, скорее всего, придётся писать свою обёртку над MultiByteToWideChar и WideCharToMultiByte.


А функции из этого файла подойдут?

К сообщению приложен файл (Encoding.rar - 12Kb) cкачать
20 дек 18, 13:51    [21769500]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
Друзья, прошу помощи с расшифровкой.
Мне удалось отправить сообщение в ФСС и получить зашифрованный ответ. Теперь бьюсь над расшифровкой. Сначала попробовал сделать через GostCryptography.dll, указывая тип провайдера из сертификата, которым подписывал сообщение
procedure TEncodeDecodeFSS(ProvCSP: string; EncryptMessage: string);
begin
    GostSoap := TGostDecryptSOAP.Create(Self);
    try
      GostSoap.Connect;
      try
          mSignature.Lines.Text := GostSoap.decryptMsg(ProvCSP, EncryptMessage);
      finally
        GostSoap.Disconnect;
      end;
    finally
      FreeAndNil(GostSoap);
    end;
end;

получаю ошибку "Данные шифра не указаны".

Попробовал по другому, застрял на ошибке "Плохие данные":

    CheckCryptoCall(CryptGetUserKey(ACryptoProvider, AT_KEYEXCHANGE, @hPrivateKey));
//    CheckCryptoCall(CryptAcquireCertificatePrivateKey(rec^.Cert, CRYPT_ACQUIRE_COMPARE_KEY_FLAG, nil, @hPrivateKey, @keySpec, @callerFree));

    // Формирование BLOB-ов публичного и сессионного ключей ФСС на основе зашифрованного ключа из ответа ФСС
    GetResponseKeysBlobs(ASOAPResponse, remotePublicKeyBlob, remoteSessionKeyBlob);

    // Получение ключа согласования импортом открытого ключа ФСС (отправителя)
    // на локальном закрытом ключе (получателя).
    // ошибка происходит здесь
    CheckCryptoCall(CryptImportKey(ACryptoProvider, @remotePublicKeyBlob[0], Length(remotePublicKeyBlob), hPrivateKey, 0, @hAgreeKey));

при этом подозреваю, что ошибку допустил где-то здесь:

procedure TfrmSignatureFromCertificate.GetResponseKeysBlobs(
  ASOAPResponse: IXMLDocument; out APublicKeyBlob,
  ASessionKeyBlob: TByteArray);

const OpenPublicKeyBlob: array[0..35] of byte =
      ($06,       // bType = PUBLICKEYBLOB
       $20,       // bVersion = 0x20
       $00, $00,
       $23, $2E, $00, $00, // KeyAlg = ALG_SID_GR3410EL
       $4D, $41, $47, $31, //Magic = GR3410_1_MAGIC
       $00, $02, $00, $00, // BitLen = 512
       // bASN1GostR3410_94_PublicKeyParameters
       $30, $12,
       $06, $07 ,
       $2A, $85, $03, $02, $02, $24, $00,
       $06, $07,
       $2A, $85, $03, $02, $02, $1E, $01);

  trBlob:  array[1..71] of byte =
  ($01, $20, $00, $00, $1E, $66, $00, $00,
   $FD, $51, $4A, $37, $1E, $66, $00, $00,
   $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, // ключ
   $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
   $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00,
   $30, $09, $06, $07,
   $2A, $85, $03, $02, $02, $1F, $01); // UKM (157,8)
var
  i: integer;
  transportNode: IXMLNode;
  transport, publicKey, sessionKey,
  sessionSV, sessionMAC: TByteArray;
  trText: string;
  enc: TUTF8Encoding;
begin
  try
    transportNode := ASOAPResponse.DocumentElement
                     .ChildNodes[1]  // Body
                     .ChildNodes[0]  // EncryptedData
                     .ChildNodes[1]  // KeyInfo
                     .ChildNodes[0]  // EncryptedKey
                     .ChildNodes[2]  // CipherData
                     .ChildNodes[0]; // CipherValue

 //изначальный код
{    transport := TNetEncoding.Base64.DecodeStringToBytes(transportNode.Text);}
//мои переделки под Delphi7
    enc := TUTF8Encoding.Create;
    try
      transport := TByteArray(enc.GetBytes(transportNode.Text));
      trText := Q_Base64Decode(enc.GetString(TBytes(transport)));
    finally
      FreeAndNil(enc);
    end;
    SetLength(transport, length(trText));
    system.Move(Windows.PByte(trText)^, Pointer(transport)^, length(trText));

    publicKey := Copy(transport, 93, 64);
    sessionKey := Copy(transport, 7, 32);
    sessionMAC := Copy(transport, 41, 4);
    sessionSV := Copy(transport, 159, 8);

//изначальный код
{    APublicKeyBlob := 
      [
       $06,       // bType = PUBLICKEYBLOB
       $20,       // bVersion = 0x20
       $00, $00,
       $23, $2E, $00, $00, // KeyAlg = ALG_SID_GR3410EL
       $4D, $41, $47, $31, //Magic = GR3410_1_MAGIC
       $00, $02, $00, $00, // BitLen = 512
       // bASN1GostR3410_94_PublicKeyParameters
       $30, $12,
       $06, $07 ,
       $2A, $85, $03, $02, $02, $24, $00,
       $06, $07,
       $2A, $85, $03, $02, $02, $1E, $01
      ] + publicKey;



    // сборка SessionKey BLOB из статической части и параметров сессионного ключа
    ASessionKeyBlob :=
    [
     $01, // bType = SIMPLEBLOB
     $20, // bVersion = 0x20
     $00,$00 ,
     $1E,$66 ,$00 ,$00, // KeyAlg = CALG_G28147
     $FD,$51 ,$4A ,$37, // Magic = G28147_MAGIC
     $1E,$66 ,$00 ,$00] // EncryptKeyAlgId = CALG_G28147
     + sessionSV + sessionKey + sessionMAC +
    [// ASN.1 Sequence + OID Header
       $30 ,$09 ,$06 ,$07,
     // OID_GOST_R28147_89_CryptoPro_A_ParamSet 1.2.643.2.2.31.1
     $2A ,$85 ,$03 ,$02 ,$02 ,$1F ,$01
    ];   }
//мои переделки под Delphi7
    SetLength(APublicKeyBlob, 100);
    for i := 0 to 35 do
      APublicKeyBlob[i] := OpenPublicKeyBlob[i];
    for i := 1 to 64 do
      APublicKeyBlob[i + 35] := publicKey[i];
    setLength(ASessionKeyBlob, 134);
    for i := 1 to 71 do
      ASessionKeyBlob[i] := trBlob[i];
    for i := 1 to 8 do
      ASessionKeyBlob[i+16] := sessionSV[i];
    for i := 1 to 32 do
      ASessionKeyBlob[i+24] := sessionKey[i];
    for i := 1 to 4 do
      ASessionKeyBlob[i+56] := sessionMAC[i];
  finally
    SetLength(sessionSV, 0);
    SetLength(sessionMac, 0);
    SetLength(sessionKey, 0);
    SetLength(publicKey, 0);
    SetLength(transport, 0);
  end;
end;


У кого стоит Embarcadero, проверьте пожалуйста, какой результат возвращает функция TNetEncoding.Base64.DecodeStringToBytes(transportNode.Text);
Если ей на вход поступает вот такое значение (CipherValue):
MIGkMCgEINMuXESbgvBOY8udqVlHxbfpPgcKAS5Ew6HTwpGhz269BASOb6SYoHgGByqFAwICHwGgYzAcBgYqhQMCAhMwEgYHKoUDAgIkAAYHKoUDAgIeAQNDAARAZMGkZ+ODNscutZgYgesDlGkN5AiubvNOhdJOaIZK+QRoVkMZnq22foPv660Khhs9zj5BTwx5u1HOITYmgEj1fwQIkfNcLhh/iDk=

С уважением, Александр.
24 дек 18, 11:11    [21771827]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
maratvg
в GostCryptography_TLB.pas будут созданы классы TGostEncryptSOAP, TGostDecryptSOAP, которые собственно и использовались.
+ для примера
function EncryptSOAP(const ASignedXml: WideString; const ACertName: string): WideString;
var
  GostEncryptSOAP: TGostEncryptSOAP;
begin
  GostEncryptSOAP := TGostEncryptSOAP.Create(nil);
  try
    GostEncryptSOAP.Connect;
    Result := GostEncryptSOAP.encryptMsg(CP_GR3410_2001_PROV_A, ACertName, ASignedXml);
  finally
    GostEncryptSOAP.Free;
  end;
end;


Если несложно, приведите пожалуйста, пример расшифровки. Для шифрования Ваш код подошёл, но пока не могу понять, как расшифровывать. Делаю так, подставляя разные параметры в decryptMsg, но каждый раз выходит одна и та же ошибка "Данные шифра не указаны".
    GostSoap := TGostDecryptSOAP.Create(Self);
    try
      GostSoap.Connect;
      try
        soapRequestDoc := LoadXMLDocument('FSSEncryptXML.xml');
        try
          decryptMessage := GostSoap.decryptMsg(CP_GR3410_2001_PROV_A, soapRequestDoc.DocumentElement.XML);
        finally
          SoapRequestDoc := nil;
        end;
      finally
        GostSoap.Disconnect;
      end;
    finally
      FreeAndNil(GostSoap);
    end;
24 дек 18, 19:42    [21772423]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
Ура, удалось разобраться с GostDecryptSOAP. Оказывается, ему надо было "скармливать" не всё сообщение, а лишь EncryptedData с содержимым. Но тут возникла другая проблема. Ошибка исчезла, но расшифровка не происходит. Подаёшь на вход зашифрованное сообщение, и его же получаешь на выходе.
Что самое интересное, вот такой код показывает, что обе функции работают нормально. Подаю на вход подписанный xml, указываю свой сертификат и вижу зашифрованное сообщение, после чего расшифровываю его и вижу исходное сообщение.

  EncSoap := TGostEncryptSOAP.Create(Self);
  try
    EncSoap.Connect;
    try
      EncryptedResponse := EncSoap.encryptMsg(CP_GR3410_2001_PROV_A, CertName, SignedXML);
      mEncryptedResponse.Text := EncryptedResponse;
    finally
      EncSoap.Disconnect;
    end;
  finally
    FreeAndNil(EncSoap);
  end;

  DecSoap := TGostDecryptSOAP.Create(Self);
  try
    DecSoap.Connect;
    try
      DecryptedResponse := DecSoap.decryptMsg(CP_GR3410_2001_PROV_A, EncryptedResponse);
      mDecryptedResponse.Text := DecryptedResponse;
    finally
      DecSoap.Disconnect;
    end;
  finally
    FreeAndNil(DecSoap);
  end;

А вот зашифровав сообщение сертификатом ФСС, ничем расшифровать его не могу. Кто-нибудь может объяснить, с чем это может быть связано.
25 дек 18, 03:11    [21772626]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
sql2012
Member

Откуда: РФ
Сообщений: 660
Shuraken,

для расшифровки нужен закрытый ключ.
25 дек 18, 11:11    [21772747]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
sql2012,

Это понятно, у меня сертификат с закрытым. Но дело в том, что расшифровка не происходит, если использовать GostDecryptSOAP.decryptMsg(aCertProv, aProvMsg). Первым параметром я указываю провайдера сертификата с закрытым ключом, вторым - ответ, полученный от ФСС. И подав зашифрованные данные на вход, я получаю их же на выходе. И у меня складывается ощущение, что эта функция просто не знает, как расшифровать.
Когда же я это делаю низкоуровневыми функциями, то ломаюсь с ошибкой "Плохие данные" при получении сессионного ключа.

    CheckCryptoCall(CryptGetUserKey(ACryptoProvider, AT_KEYEXCHANGE, @hPrivateKey));

    // Формирование BLOB-ов публичного и сессионного ключей ФСС на основе зашифрованного ключа из ответа ФСС
    GetResponseKeysBlobs(ASOAPResponse, remotePublicKeyBlob, remoteSessionKeyBlob);

    // Получение ключа согласования импортом открытого ключа ФСС (отправителя)
    // на локальном закрытом ключе (получателя)
    CheckCryptoCall(CryptImportKey(ACryptoProvider, @remotePublicKeyBlob[0], Length(remotePublicKeyBlob), hPrivateKey, 0, @hAgreeKey));

    // Установка параметра PRO_EXPORT алгоритма ключа согласования
    keyParam := CALG_PRO_EXPORT;
    CheckCryptoCall(CryptSetKeyParam(hAgreeKey, KP_ALGID, @keyParam, 0));

    // Получение сессионного ключа импортом сессионного ключа ФСС (отправителя) на ключе согласования
    // Вот здесь и происходит ошибка.
    CheckCryptoCall(CryptImportKey(ACryptoProvider, @remoteSessionKeyBlob[0], Length(remoteSessionKeyBlob), hAgreeKey, 0, @hSessionKey));


И я пытаюсь разобраться, что надо подать на вход функции GostDecryptSOAP, чтобы получить расшифрованные данные, и в чём причина ошибки "плохие данные" при работе с низкоуровневыми функциями. В этом я и прошу помочь мне.
В аттаче dll и обёртка для делфи

К сообщению приложен файл (GostCryptography.rar - 79Kb) cкачать
25 дек 18, 11:30    [21772769]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
maratvg
Member

Откуда: 74
Сообщений: 108
Shuraken,

Насколько помню в ответе от ФСС надо подменить их сертификат своим перед расшифровкой. Нашел вот такую процедуру. Попробуйте сделать что-то похожее.

+

function DecryptXml(AXml: IXmlDocument; const AOwnerCertName {это сертификат НАШЕЙ организации}: string): string;
var
  S: string;
  Node: IXmlNode;
begin
  Node := FindPath(AXml, '/SOAP-ENV:Envelope/SOAP-ENV:Body/xenc:EncryptedData/ds:KeyInfo/xenc:EncryptedKey/ds:KeyInfo/ds:X509Data/ds:X509Certificate');
  if Node = nil then
    Exit;
  Node.Text := GetCertCertificate(AOwnerCertName); 
  Node := FindPath(AXml, '/SOAP-ENV:Envelope/SOAP-ENV:Body/xenc:EncryptedData');
  S := Node.XML;
  S := DecryptSOAP(S); // вызов GostDecryptSOAP.decryptMsg
  S := '<?xml version=''1.0'' encoding=''UTF-8''?>' + S;
  Result := S;
end;

// получение сертификата в base64 кодировке по переданному имени сертификата
function GetCertCertificate(const ACertName: string): AnsiString;
var
  Cert: PCCERT_CONTEXT;
begin
  Cert := FindCertificate(ACertName);
  if Cert <> nil then
    try
      Result := EncodeBase64(Cert.pbCertEncoded, Cert.cbCertEncoded);
    finally
      CertFreeCertificateContext(Cert);
    end;
end;
25 дек 18, 14:05    [21772951]     Ответить | Цитировать Сообщить модератору
 Re: Электронный больничный ЭЛН  [new]
Shuraken
Member

Откуда:
Сообщений: 622
maratvg
Shuraken,

Насколько помню в ответе от ФСС надо подменить их сертификат своим перед расшифровкой. Нашел вот такую процедуру. Попробуйте сделать что-то похожее.



Спасибо за совет, попробовал, но получил ошибку "плохие данные". Использовал сертификат с закрытым ключом, который по структуре совпадает с сертификатом ФСС. Попробовал другие - та же самая картина. Интересно, а чьим открытым ключом они шифруют ответные сообщения. Я-то предполагал, что они расшифровывают закрытым ключом, берут открытый сертификат из подписи сообщения и шифруют им. И в этом случае в ответном сообщении я увижу открытый ключ своего сертификата. Но нет.
25 дек 18, 15:13    [21773023]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 2 3 [4] 5 6 7   вперед  Ctrl      все
Все форумы / Delphi Ответить