Статус: Новичок
Группы: Участники
Зарегистрирован: 10.08.2019(UTC) Сообщений: 6
|
Фрагмент кода, который расшифровывает пакет (убрана обработка ошибок и декларация переменных): Код://transportKey, aDataText = base64 encoded binnary
function DecryptSOAPResponse( const transportKey, aDataText : string ): widestring;
begin
// Получение локального закрытого ключа
CryptGetUserKey(CryptoProvider, AT_KEYEXCHANGE, @hPrivateKey);
// Формирование BLOB-ов публичного и сессионного ключей ФСС на основе зашифрованного ключа из ответа ФСС
GetResponseKeysBlobs(transportKey, remotePublicKeyBlob, remoteSessionKeyBlob);
// Получение ключа согласования импортом открытого ключа ФСС (отправителя)
// на локальном закрытом ключе (получателя)
CryptImportKey(CryptoProvider, @remotePublicKeyBlob[0], Length(remotePublicKeyBlob),
hPrivateKey, 0, @hAgreeKey);
// Установка параметра PRO_EXPORT алгоритма ключа согласования
keyParam := CALG_PRO_EXPORT;
CryptSetKeyParam(hAgreeKey, KP_ALGID, @keyParam, 0);
// Получение сессионного ключа импортом сессионного ключа ФСС (отправителя) на ключе согласования
CryptImportKey(CryptoProvider,
@remoteSessionKeyBlob[0], Length(remoteSessionKeyBlob),
hAgreeKey, 0, @hSessionKey);
// Установка режима шифрования CBC
keyParam := CRYPT_MODE_CBC;
CryptSetKeyParam(hSessionKey, KP_MODE, @keyParam, 0);
// Установка режима паддинга
keyParam := 0;
CryptSetKeyParam(hSessionKey, KP_PADDING, @keyParam, 0);
// Получение зашифрованных данных из ответа ФСС
// удаляем переносы строк, удаляем смещения Tab, переводим base64 в TBytes
responseData := DecodeBytes( DeleteOther( aDataText ) );
// Получение вектора инициализации (первые 8 байт ответа)
initVector := Copy(responseData, 0, 8);
// Получение зашифрованного запроса
decryptedData := Copy(responseData, 8, Length(responseData) - 8);
// Установка вектора инициализации
CryptSetKeyParam(hSessionKey, KP_IV, @initVector[0], 0);
// Определение размера буфера зашифрованного запроса
decryptedDataLen := Length(decryptedData);
// Расшифровка данных запроса ---- вот здесь и получаем "Плохие данные"
CryptDecrypt(hSessionKey, 0, true, 0, @decryptedData[0], @decryptedDataLen);
// Обновление размера буфера расшифрованных данных
SetLength(decryptedData, decryptedDataLen);
// Формирование конечного содержания (устранение последствий паддинга и т.п.)
Result := CreateDecryptedContent(decryptedData);
end;
// Формирование BLOB-ов публичного и сессионного ключей ФСС на основе зашифрованного ключа из ответа ФСС
procedure GetResponseKeysBlobs(const transportKey : string;
out APublicKeyBlob: TBytes; out ASessionKeyBlob: TBytes);
var
transport, publicKey, sessionKey, sessionSV, sessionMAC: TBytes;
begin
// удаляем переносы строк, удаляем смещения Tab, переводим base64 в TBytes
transport := DecodeBytes( DeleteOther(transportKey) );
publicKey := Copy(transport, 98, 64); // 98, 64 открытый ключ отправителя
sessionKey := Copy(transport, 7, 32); // 7, 32 зашифрованный сессионный ключ
sessionMAC := Copy(transport, 41, 4); // 41, 4 MAC сессионного ключа
sessionSV := Copy(transport, 164, 8); // 164, 8 синхропосылка (UKM)
APublicKeyBlob := bytesMerge( [
Array2Dyn([
$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, $13,
$06, $07, $2A, $85, $03, $02, $02, $24, $00,
$06, $08, $2A, $85, $03, $07, $01, $01, $02, $02
]), publicKey ] );
ASessionKeyBlob := bytesMerge( [
Array2Dyn([
$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,
Array2Dyn([// ASN.1 Sequence + OID Header
$30 ,$0B ,$06 ,$09,
// OID_GOST_R28147_89_CryptoPro_A_ParamSet 1.2.643.7.1.2.5.1.1
$2A ,$85 ,$03 ,$07 ,$01 ,$02 ,$05, $01, $01
])]);
end;
Отредактировано пользователем 16 декабря 2025 г. 18:08:35(UTC)
| Причина: Не указана
|