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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Michael Makushev  
#1 Оставлено : 29 февраля 2008 г. 16:58:03(UTC)
Michael Makushev

Статус: Участник

Группы: Участники
Зарегистрирован: 11.01.2008(UTC)
Сообщений: 22
Откуда: Санкт-Петербург

После длительных мучений установил CSP версии 3.6 триальный.

используя указанный ниже код, пытаюсь сделать криптование некоторой строки. Контейнер с сертификатом находится на носителе типа дискета. Криптование в два этапа вызова функции CryptEncryptMessage прошло на "ура". Декриптование ломается на втором вызове, то есть первый (для определения размера декриптованногого буфера) срабатывает и дает размер буфера, а второй (выделен жирным шрифтом) ломается с Access Violation. C чем это может быть связано?

Цитата:
try
if not CryptAcquireContext(@hProv, 'MAKUSHEV', nil, ProvType, 0) then
begin
exit;
end;

hSystemStore := CertOpenSystemStore(0, 'MY');

encType := PKCS_7_ASN_ENCODING or X509_ASN_ENCODING;
myCert := 'Mik';
pCert := CertFindCertificateInStore(hSystemStore,
encType,
0,
CERT_FIND_SUBJECT_STR,
myCert,
nil);

new(pMsgPara);
ZeroMemory(pMsgPara, SizeOf(pMsgPara^));
with pMsgPara^ do
begin
cbSize := SizeOf(pMsgPara^);
dwMsgEncodingType := encType;
ContentEncryptionAlgorithm.pszObjId := CertAlgIdToOID(CALG_RC4);
hCryptProv := hProv;
end;

test := '1234567890';

arCertContext := TMemoryStream.Create;
arCertContext.SetSize(arCertContext.Size + SizeOf(Pointer));
TPointerList(arCertContext.Memory^)[0] := PCCERT_CONTEXT(pCert);

ret := CryptEncryptMessage(pMsgPara, 1, arCertContext.Memory, PByte(PChar(test)), length(test), nil, @BufSize);

if ret then
begin
pbEncBlob := StrAlloc(BufSize);
ret := CryptEncryptMessage(pMsgPara, 1, arCertContext.Memory, PByte(PChar(test)), length(test), PByte(pbEncBlob), @BufSize);
end
else
showMessage(GetCryptError(GetLastError));

if ret then
begin
AssignFile(F, 'c:\111');
Reset(F, 1);
BlockWrite(F, pbEncBlob^, BufSize, BufSize);
CloseFile(F);
end;

new(pMsgPara2);
ZeroMemory(pMsgPara2, SizeOf(pMsgPara2^));
with pMsgPara2^ do
begin
cbSize := SizeOf(pMsgPara2^);
dwMsgAndCertEncodingType := encType;
cCertStore := 1;
rghCertStore := hSystemStore;
end;

ret := CryptDecryptMessage(pMsgPara2, PByte(pbEncBlob), BufSize, nil, @ResBufSize, nil);

if ret then
begin
pbDecBlob := StrAlloc(ResBufSize);
ret := CryptDecryptMessage(pMsgPara2, PByte(pbDecBlob) {PByte(pbEncBlob)}, BufSize, PByte(pbDecBlob), @ResBufSize, nil);
if not ret then
showMessage(GetCryptError(GetLastError));
end
else
showMessage(GetCryptError(GetLastError));
Offline Kirill Sobolev  
#2 Оставлено : 29 февраля 2008 г. 18:59:05(UTC)
Кирилл Соболев

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

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
А что вот эта конструкция означает PByte(pbDecBlob) {PByte(pbEncBlob)}?
Техническую поддержку оказываем тут
Наша база знаний
Offline Michael Makushev  
#3 Оставлено : 3 марта 2008 г. 11:14:13(UTC)
Michael Makushev

Статус: Участник

Группы: Участники
Зарегистрирован: 11.01.2008(UTC)
Сообщений: 22
Откуда: Санкт-Петербург

Kirill Sobolev написал:
А что вот эта конструкция означает PByte(pbDecBlob) {PByte(pbEncBlob)}?

то же самое что и PByte(pbDecBlob)
в Паскале блочные ограничители другие. то что вас смутило - это комментарии
Offline Kirill Sobolev  
#4 Оставлено : 3 марта 2008 г. 14:09:30(UTC)
Кирилл Соболев

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

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
Тогда почему в 1м вызове у Вас передается PByte(pbEncBlob), что правильно, а во 2м - PByte(pbDecBlob), что неверно?
Техническую поддержку оказываем тут
Наша база знаний
Offline Michael Makushev  
#5 Оставлено : 3 марта 2008 г. 20:42:57(UTC)
Michael Makushev

Статус: Участник

Группы: Участники
Зарегистрирован: 11.01.2008(UTC)
Сообщений: 22
Откуда: Санкт-Петербург

Kirill Sobolev написал:
Тогда почему в 1м вызове у Вас передается PByte(pbEncBlob), что правильно, а во 2м - PByte(pbDecBlob), что неверно?

d'oh! Brick wall Brick wall Brick wall
Старый вариант написал. То что вы видите срабатывало без AV но с отрицательным результатом (false) и нулевым кодом.
если я делаю вот так


Цитата:
...
cCertStore := 1;
rghCertStore := hSystemStore;
end;

ret := CryptDecryptMessage(pMsgPara2, PByte(pbEncBlob), BufSize, nil, @ResBufSize, nil);

if ret then
begin
pbDecBlob := StrAlloc(ResBufSize);
ret := CryptDecryptMessage(pMsgPara2, PByte(pbEncBlob), BufSize, PByte(pbDecBlob), @ResBufSize, nil);
if not ret then
showMessage(GetCryptError(GetLastError));
end
else
showMessage(GetCryptError(GetLastError));
...


то оно как раз и ниспадает в AV

Как вариант я нашел кусок кода из SDK где перед раскриптовкой данные прогоняются через некоторую тайную функцию ByteToStr
Перевести её работу на Паскаль сложности не представляет. Но понять логический смысл её - мне недоступно. И потом может ли её отсутсвие повлиять на возникновение AV, ведь при криптовании вызов обратной ей не происходит...
Offline Kirill Sobolev  
#6 Оставлено : 3 марта 2008 г. 21:05:51(UTC)
Кирилл Соболев

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

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
а в ResBufSize правильный размер возвращается?
Техническую поддержку оказываем тут
Наша база знаний
Offline Michael Makushev  
#7 Оставлено : 3 марта 2008 г. 21:23:31(UTC)
Michael Makushev

Статус: Участник

Группы: Участники
Зарегистрирован: 11.01.2008(UTC)
Сообщений: 22
Откуда: Санкт-Петербург

Kirill Sobolev написал:
а в ResBufSize правильный размер возвращается?

А что значит правильный? Теоретически неправильный... на 6 байт больше (то есть 16 вместо исходных 10).... но как это интерпретировать я не знаю...
Offline Kirill Sobolev  
#8 Оставлено : 4 марта 2008 г. 14:02:21(UTC)
Кирилл Соболев

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

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
Нет, это нормально - первый вызов функции всегда возвращает немного больший размер.
а можно еще взглянуть на описание pMsgPara2?
Техническую поддержку оказываем тут
Наша база знаний
Offline Michael Makushev  
#9 Оставлено : 4 марта 2008 г. 16:36:45(UTC)
Michael Makushev

Статус: Участник

Группы: Участники
Зарегистрирован: 11.01.2008(UTC)
Сообщений: 22
Откуда: Санкт-Петербург

Kirill Sobolev написал:
Нет, это нормально - первый вызов функции всегда возвращает немного больший размер.
а можно еще взглянуть на описание pMsgPara2?

конечно

Цитата:

arCertContext: TMemoryStream;
hProv: HCRYPTPROV;
hSystemStore: HCERTSTORE;
pCert: PCCERT_CONTEXT;
msgPara: CRYPT_ENCRYPT_MESSAGE_PARA;
EncryptedAlgorithm: CRYPT_ALGORITHM_IDENTIFIER;
pbDecBlob2, pbDecBlob, pbEncBlob: PChar;
pMsgPara: PCRYPT_ENCRYPT_MESSAGE_PARA;
pMsgPara2: PCRYPT_DECRYPT_MESSAGE_PARA;
Offline Kirill Sobolev  
#10 Оставлено : 4 марта 2008 г. 17:46:51(UTC)
Кирилл Соболев

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

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
да, вот что такое PCRYPT_DECRYPT_MESSAGE_PARA?
Техническую поддержку оказываем тут
Наша база знаний
Offline Michael Makushev  
#11 Оставлено : 5 марта 2008 г. 17:05:16(UTC)
Michael Makushev

Статус: Участник

Группы: Участники
Зарегистрирован: 11.01.2008(UTC)
Сообщений: 22
Откуда: Санкт-Петербург

Kirill Sobolev написал:
да, вот что такое PCRYPT_DECRYPT_MESSAGE_PARA?


Смотрим по аналогии в SDK для Криптопро

Цитата:
// Объявление и инициализация локальных переменных.
DWORD cbDecryptedMessage;
char* EncryptedString = new char[(cbEncryptedBlob * 2) +1];
HCERTSTORE CertStoreArray[] = {hStoreHandle};
CRYPT_DECRYPT_MESSAGE_PARA DecryptParams;
DWORD DecryptParamsSize = sizeof(DecryptParams);
BYTE* pbDecryptedMessage;
LPSTR DecryptedString;
BOOL fReturn = TRUE;



Теперь описание модуля-хедера для паскаля

Цитата:
//+-------------------------------------------------------------------------
// The CRYPT_DECRYPT_MESSAGE_PARA are used for decrypting messages.
//
// The CertContext to use for decrypting a message is obtained from one
// of the specified cert stores. An encrypted message can have one or
// more recipients. The recipients are identified by their CertId (Issuer
// and SerialNumber). The cert stores are searched to find the CertContext
// corresponding to the CertId.
//
// Only CertContexts in the store with either
// the CERT_KEY_PROV_HANDLE_PROP_ID or CERT_KEY_PROV_INFO_PROP_ID set
// can be used. Either property specifies the private exchange key to use.
//
// cbSize must be set to the sizeof(CRYPT_DECRYPT_MESSAGE_PARA) or else
// LastError will be updated with E_INVALIDARG.
//--------------------------------------------------------------------------
type
PCRYPT_DECRYPT_MESSAGE_PARA = ^CRYPT_DECRYPT_MESSAGE_PARA;
CRYPT_DECRYPT_MESSAGE_PARA = record
cbSize :DWORD;
dwMsgAndCertEncodingType :DWORD;
cCertStore :DWORD;
rghCertStore :PHCERTSTORE;
end;


вроде все соответствует
Offline Kirill Sobolev  
#12 Оставлено : 5 марта 2008 г. 19:07:57(UTC)
Кирилл Соболев

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

Группы: Участники
Зарегистрирован: 25.12.2007(UTC)
Сообщений: 1,732
Мужчина
Откуда: КРИПТО-ПРО

Поблагодарили: 177 раз в 168 постах
Да, соответствует.
но у Вас объявлено
Цитата:
rghCertStore :PHCERTSTORE

что верно, т.к. теоретически хранилищ для поиска может быть несколько.
а в коде
Цитата:
rghCertStore := hSystemStore
причем
Цитата:
hSystemStore: HCERTSTORE

соответственно функция лезет искать сертификат для расшифровки по адресу, который на самом деле является хендлом хранилища и на этом падает.
должно быть
Цитата:
rghCertStore := @hSystemStore
Техническую поддержку оказываем тут
Наша база знаний
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.