Статус: Участник
Группы: Участники
Зарегистрирован: 12.08.2020(UTC) Сообщений: 22 Откуда: Москва
|
Автор: Андрей * Какое время в итоге стало на расшифровку? Пара секунд на 160 МБ. Очень быстро. Причем, когда после расшифровки я делаю проверку подписи — там тоже цикл загрузки файла и он выполняется уже быстро, не тормозит так как при загрузке зашифрованного файла. Хотя цикл точно такой же с апдейтом. Я не понимаю почему при загрузке зашифрованного файла все тоже самое дико тормозит. Ну, то есть, при расшифровке я как ты и посоветовал делаю апдейт и тут же дешифрацию по кусочкам 1 МБ. Получаю расшифрованный и подписанный файл. Затем с этим файлом работаю по снятию подписи и ее проверке. Для этого делаю все как в LargeCms без изменения — полный цикл с апдейтами по кусочкам 1 МБ, но уже без расшифрования. Когда весь цикл отработал и я уже получил выходной файл без подписи, я запускаю процедуру проверки подписи. И вот этот второй цикл работает тоже 2-3 секунды. Получается, что при импорте зашифрованного файла, если его сразу не расшифровывать, то происходит какое-то нелинейное затормаживание, как будто каждый раз при добавлении нового кусочка в память происходит какая-то сверка, сложность которой геометрически растет с размером загруженного файла. Но как только часть файла расшифрована, эти тормоза прекращаются.
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,340 Сказал «Спасибо»: 550 раз Поблагодарили: 2212 раз в 1727 постах
|
Автор: esolomonov Автор: Андрей * Какое время в итоге стало на расшифровку? Пара секунд на 160 МБ. Очень быстро. Причем, когда после расшифровки я делаю проверку подписи — там тоже цикл загрузки файла и он выполняется уже быстро, не тормозит так как при загрузке зашифрованного файла. Хотя цикл точно такой же с апдейтом. Я не понимаю почему при загрузке зашифрованного файла все тоже самое дико тормозит. Ну, то есть, при расшифровке я как ты и посоветовал делаю апдейт и тут же дешифрацию по кусочкам 1 МБ. Получаю расшифрованный и подписанный файл. Затем с этим файлом работаю по снятию подписи и ее проверке. Для этого делаю все как в LargeCms без изменения — полный цикл с апдейтами по кусочкам 1 МБ, но уже без расшифрования. Когда весь цикл отработал и я уже получил выходной файл без подписи, я запускаю процедуру проверки подписи. И вот этот второй цикл работает тоже 2-3 секунды. Получается, что при импорте зашифрованного файла, если его сразу не расшифровывать, то происходит какое-то нелинейное затормаживание, как будто каждый раз при добавлении нового кусочка в память происходит какая-то сверка, сложность которой геометрически растет с размером загруженного файла. Но как только часть файла расшифрована, эти тормоза прекращаются. Бинго... Я же спрашивал ("заранее") - по коду из LargeCms "всё понятно"? Мне вот не понятно, почему там решили прочитать ВЕСЬ файл и только в конце позвать Decrypt! (автор LargeCms не тестировал на больших файлах?) |
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,340 Сказал «Спасибо»: 550 раз Поблагодарили: 2212 раз в 1727 постах
|
Автор: Андрей * попробовал через largecms - 13с на 10 мб файле + нагружает ЦП посмотрел вызовы...
Вам понятно, что делает ProcessMessage?
почему потом вызывается CheckEnvelopeAlg? и... в финале Decrypt? вот) |
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 12.08.2020(UTC) Сообщений: 22 Откуда: Москва
|
Автор: Андрей * вот) У меня беда. При активной работе на расшифровке, через какое-то время сервис вылетает с ошибкой в ntdll.dll. Методом коментирования я выяснил, что ошибка случается, если вызывается функция открытия хранилища сертификата: Код:hStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM_REGISTRY,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
IntPtr.Zero,
CERT_SYSTEM_STORE_LOCAL_MACHINE,
new SafeMsgHandle(Marshal.StringToHGlobalUni("MY"))
);
В оригинале использовалась функция CertOpenSystemStore, но мне надо открывать хранилище локальной машины, через CertOpenSystemStore это сделать нельзя, это прямо написано в документации. Высвобождение памяти делалось в оригинале вот так: Код:Win32.CertCloseStore(handle, Win32.CERT_CLOSE_STORE_FORCE_FLAG);
Я поменял на так: Код:Win32.CertCloseStore(handle, 0);
Не помогает. Уже все перепробовал. Как только код доходит до CertOpenStore, то на второй, 10-й или 20-й итерации сервис вылетает. То есть ошибка происходит не сразу, не при первой же итерации. Какой-то накопительный эффект. Поэтому я и подумал что не правильно высвобождается память. Если использовать CertOpenSystemStore , такой проблемы нет, но через CertOpenSystemStore я не нахожу сертификат в локальной машине.
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,340 Сказал «Спасибо»: 550 раз Поблагодарили: 2212 раз в 1727 постах
|
Цитата:то на второй, 10-й или 20-й итерации сервис вылетает. Какие итерации - расшифрование разных файлов? Сделать открытие хранилища один раз - не предлагать? |
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 12.08.2020(UTC) Сообщений: 22 Откуда: Москва
|
Автор: Андрей * Цитата:то на второй, 10-й или 20-й итерации сервис вылетает. Какие итерации - расшифрование разных файлов? Сделать открытие хранилища один раз - не предлагать? Я для теста расшифровываю один и тот же файл. Открывать хранилище один раз не подходит, да. В реальности файл будет появляться внезапно и держать хранилище всегда открытым не вариант. К тому же это костыли какие-то. Хранилище же должно нормально открываться и закрываться хоть сто пицот раз. Может я как-то не правильно его открываю? Просто обгуглился, примеров в интернете найти не могу, тем более под C#.
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 26.07.2011(UTC) Сообщений: 13,340 Сказал «Спасибо»: 550 раз Поблагодарили: 2212 раз в 1727 постах
|
Автор: esolomonov Автор: Андрей * Цитата:то на второй, 10-й или 20-й итерации сервис вылетает. Какие итерации - расшифрование разных файлов? Сделать открытие хранилища один раз - не предлагать? Я для теста расшифровываю один и тот же файл. Открывать хранилище один раз не подходит, да. В реальности файл будет появляться внезапно и держать хранилище всегда открытым не вариант. К тому же это костыли какие-то. Хранилище же должно нормально открываться и закрываться хоть сто пицот раз. Может я как-то не правильно его открываю? Просто обгуглился, примеров в интернете найти не могу, тем более под C#. У меня не воспроизводилось. Пример минимальный можно...? На сервере много сертификатов? Или ограниченное кол-во? В хранилище идти, чтобы в итоге получить имя контейнера... Можно и обойтись известным перечнем (серийный номер, контейнер) |
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 12.08.2020(UTC) Сообщений: 22 Откуда: Москва
|
Автор: Андрей * У меня не воспроизводилось. Пример минимальный можно...?
На сервере много сертификатов? Или ограниченное кол-во? В хранилище идти, чтобы в итоге получить имя контейнера... Можно и обойтись известным перечнем (серийный номер, контейнер)
Минимальный пример: Код:public unsafe static void ProcessAndDecryptMessageTest(SafeMsgHandle hMsg, FileStream file, string serialNumber = null)
{
SafeStoreHandle hStore = SafeStoreHandle.Null;
try
{
hStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM_REGISTRY,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
IntPtr.Zero,
CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG,
new SafeMsgHandle(Marshal.StringToHGlobalUni("MY"))
);
if ((hStore == null) || (hStore.IsInvalid))
{
throw new Exception("Ошибка открытия хранилища #" + Marshal.GetLastWin32Error().ToString(), new Win32Exception(Marshal.GetLastWin32Error()));
}
}
finally
{
hStore.Dispose();
}
}
CERT_STORE_READONLY_FLAG — это уже эксперимент. И на всякий случай SafeStoreHandle: Код:class SafeStoreHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeStoreHandle()
: base(true)
{
}
public SafeStoreHandle(IntPtr handle)
: base(true)
{
SetHandle(handle);
}
public static SafeStoreHandle Null
{
get { return new SafeStoreHandle(IntPtr.Zero); }
}
protected override bool ReleaseHandle()
{
//Win32.CertCloseStore(handle, Win32.CERT_CLOSE_STORE_FORCE_FLAG);
Win32.CertCloseStore(handle, 0);
return true;
}
}
Выполняется 4 раза подряд и потом: Код:Имя сбойного приложения: BonkoService.exe, версия: 1.0.0.0, метка времени: 0x5f36d0aa
Имя сбойного модуля: ntdll.dll, версия: 6.3.9600.18438, метка времени: 0x57ae642e
Код исключения: 0xc0000374
Смещение ошибки: 0x00000000000f1b70
Идентификатор сбойного процесса: 0x2eb4
Время запуска сбойного приложения: 0x01d672649bdf7269
Путь сбойного приложения: C:\Mobi\.tfs\Bonko2019\BonkoService\bin\Debug\BonkoService.exe
Путь сбойного модуля: C:\Windows\SYSTEM32\ntdll.dll
Идентификатор отчета: dcfe5480-de57-11ea-80f1-000c29f8177a
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 12.08.2020(UTC) Сообщений: 22 Откуда: Москва
|
Нашел ошибку. Код:hStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM_REGISTRY,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
IntPtr.Zero,
CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG,
new SafeMsgHandle(Marshal.StringToHGlobalUni("MY"))
);
В этом дело: new SafeMsgHandle(Marshal.StringToHGlobalUni("MY")) В Win32.cs CertOpenStore определена так: Код:[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern SafeStoreHandle CertOpenStore(
int lpszStoreProvider,
int dwMsgAndCertEncodingType,
IntPtr hCryptProv,
int dwFlags,
SafeMsgHandle pvPara
);
Разработчик не рассчитывал использовать эту функцию для доступа в системное хранилище, а только в хранилище файла, поэтому сделал последний параметр типа SafeMsgHandle, а у него в Dispose висит вот это: Win32.CryptMsgClose(handle); А вызов CryptMsgClose уменьшает счетчик открытых дескрипторов. Я не знал этого. Получается, что каждое высвобождение памяти от hStore приводило к уменьшению счетчика дескриптора сообщения, которое тут вообще не при чем. В общем я сделал перегрузку этой функции на вот такую: Код:[DllImport("Crypt32.dll", SetLastError = true)]
internal static extern SafeStoreHandle CertOpenStore(
int lpszStoreProvider,
int dwMsgAndCertEncodingType,
IntPtr hCryptProv,
int dwFlags,
SafeNTHeapHandle pvPara
);
И вызываю так: Код:hStore = CertOpenStore(
CERT_STORE_PROV_SYSTEM,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
IntPtr.Zero,
CERT_SYSTEM_STORE_LOCAL_MACHINE,
new SafeNTHeapHandle(Marshal.StringToHGlobalUni("MY"))
);
Уже 353 итерации... Пока работает :)
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close