Статус: Активный участник
Группы: Участники
Зарегистрирован: 30.05.2018(UTC) Сообщений: 38  Сказал(а) «Спасибо»: 7 раз Поблагодарили: 2 раз в 2 постах
|
Попробовал расшифровать по другому, застрял на ошибке "Плохие данные": Код:
CheckCryptoCall(CryptGetUserKey(ACryptoProvider, AT_KEYEXCHANGE, @hPrivateKey));
// Формирование BLOB-ов публичного и сессионного ключей ФСС на основе зашифрованного ключа из ответа ФСС
GetResponseKeysBlobs(ASOAPResponse, remotePublicKeyBlob, remoteSessionKeyBlob);
// Получение ключа согласования импортом открытого ключа ФСС (отправителя)
// на локальном закрытом ключе (получателя).
// ошибка происходит здесь
CheckCryptoCall(CryptImportKey(ACryptoProvider, @remotePublicKeyBlob[0], Length(remotePublicKeyBlob), hPrivateKey, 0, @hAgreeKey));
при этом подозреваю, что ошибку допустил где-то здесь: Код:
procedure Tfrm.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= С уважением, Александр.
|