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

Уведомление

Icon
Error

3 Страницы<123
Опции
К последнему сообщению К первому непрочитанному
Offline esolomonov  
#41 Оставлено : 14 августа 2020 г. 13:02:11(UTC)
esolomonov

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

Группы: Участники
Зарегистрирован: 12.08.2020(UTC)
Сообщений: 22
Российская Федерация
Откуда: Москва

Автор: Андрей * Перейти к цитате
Какое время в итоге стало на расшифровку?


Пара секунд на 160 МБ. Очень быстро. Причем, когда после расшифровки я делаю проверку подписи — там тоже цикл загрузки файла и он выполняется уже быстро, не тормозит так как при загрузке зашифрованного файла. Хотя цикл точно такой же с апдейтом. Я не понимаю почему при загрузке зашифрованного файла все тоже самое дико тормозит.

Ну, то есть, при расшифровке я как ты и посоветовал делаю апдейт и тут же дешифрацию по кусочкам 1 МБ. Получаю расшифрованный и подписанный файл. Затем с этим файлом работаю по снятию подписи и ее проверке. Для этого делаю все как в LargeCms без изменения — полный цикл с апдейтами по кусочкам 1 МБ, но уже без расшифрования. Когда весь цикл отработал и я уже получил выходной файл без подписи, я запускаю процедуру проверки подписи. И вот этот второй цикл работает тоже 2-3 секунды.

Получается, что при импорте зашифрованного файла, если его сразу не расшифровывать, то происходит какое-то нелинейное затормаживание, как будто каждый раз при добавлении нового кусочка в память происходит какая-то сверка, сложность которой геометрически растет с размером загруженного файла. Но как только часть файла расшифрована, эти тормоза прекращаются.
Offline Андрей *  
#42 Оставлено : 14 августа 2020 г. 13:57:58(UTC)
Андрей *

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 9,582
Мужчина
Российская Федерация

Сказал «Спасибо»: 345 раз
Поблагодарили: 1379 раз в 1065 постах
Автор: esolomonov Перейти к цитате
Автор: Андрей * Перейти к цитате
Какое время в итоге стало на расшифровку?


Пара секунд на 160 МБ. Очень быстро. Причем, когда после расшифровки я делаю проверку подписи — там тоже цикл загрузки файла и он выполняется уже быстро, не тормозит так как при загрузке зашифрованного файла. Хотя цикл точно такой же с апдейтом. Я не понимаю почему при загрузке зашифрованного файла все тоже самое дико тормозит.

Ну, то есть, при расшифровке я как ты и посоветовал делаю апдейт и тут же дешифрацию по кусочкам 1 МБ. Получаю расшифрованный и подписанный файл. Затем с этим файлом работаю по снятию подписи и ее проверке. Для этого делаю все как в LargeCms без изменения — полный цикл с апдейтами по кусочкам 1 МБ, но уже без расшифрования. Когда весь цикл отработал и я уже получил выходной файл без подписи, я запускаю процедуру проверки подписи. И вот этот второй цикл работает тоже 2-3 секунды.

Получается, что при импорте зашифрованного файла, если его сразу не расшифровывать, то происходит какое-то нелинейное затормаживание, как будто каждый раз при добавлении нового кусочка в память происходит какая-то сверка, сложность которой геометрически растет с размером загруженного файла. Но как только часть файла расшифрована, эти тормоза прекращаются.


Бинго... Я же спрашивал ("заранее") - по коду из LargeCms "всё понятно"?
Мне вот не понятно, почему там решили прочитать ВЕСЬ файл и только в конце позвать Decrypt! (автор LargeCms не тестировал на больших файлах?)
Техническую поддержку оказываем тут
Наша база знаний
Offline Андрей *  
#43 Оставлено : 14 августа 2020 г. 13:59:12(UTC)
Андрей *

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 9,582
Мужчина
Российская Федерация

Сказал «Спасибо»: 345 раз
Поблагодарили: 1379 раз в 1065 постах
Автор: Андрей * Перейти к цитате
попробовал через largecms - 13с на 10 мб файле + нагружает ЦП
посмотрел вызовы...

Вам понятно, что делает ProcessMessage?

почему потом вызывается CheckEnvelopeAlg?
и... в финале Decrypt?
d'oh!

вот)
Техническую поддержку оказываем тут
Наша база знаний
Offline esolomonov  
#44 Оставлено : 14 августа 2020 г. 16:45:17(UTC)
esolomonov

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

Группы: Участники
Зарегистрирован: 12.08.2020(UTC)
Сообщений: 22
Российская Федерация
Откуда: Москва

Автор: Андрей * Перейти к цитате
d'oh!

вот)


У меня беда. При активной работе на расшифровке, через какое-то время сервис вылетает с ошибкой в 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 я не нахожу сертификат в локальной машине.
Offline Андрей *  
#45 Оставлено : 14 августа 2020 г. 17:03:03(UTC)
Андрей *

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 9,582
Мужчина
Российская Федерация

Сказал «Спасибо»: 345 раз
Поблагодарили: 1379 раз в 1065 постах
Цитата:
то на второй, 10-й или 20-й итерации сервис вылетает.


Какие итерации - расшифрование разных файлов?
Сделать открытие хранилища один раз - не предлагать?
Техническую поддержку оказываем тут
Наша база знаний
Offline esolomonov  
#46 Оставлено : 14 августа 2020 г. 17:05:48(UTC)
esolomonov

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

Группы: Участники
Зарегистрирован: 12.08.2020(UTC)
Сообщений: 22
Российская Федерация
Откуда: Москва

Автор: Андрей * Перейти к цитате
Цитата:
то на второй, 10-й или 20-й итерации сервис вылетает.


Какие итерации - расшифрование разных файлов?
Сделать открытие хранилища один раз - не предлагать?


Я для теста расшифровываю один и тот же файл. Открывать хранилище один раз не подходит, да. В реальности файл будет появляться внезапно и держать хранилище всегда открытым не вариант. К тому же это костыли какие-то. Хранилище же должно нормально открываться и закрываться хоть сто пицот раз. Может я как-то не правильно его открываю? Просто обгуглился, примеров в интернете найти не могу, тем более под C#.
Offline Андрей *  
#47 Оставлено : 14 августа 2020 г. 19:06:08(UTC)
Андрей *

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 9,582
Мужчина
Российская Федерация

Сказал «Спасибо»: 345 раз
Поблагодарили: 1379 раз в 1065 постах
Автор: esolomonov Перейти к цитате
Автор: Андрей * Перейти к цитате
Цитата:
то на второй, 10-й или 20-й итерации сервис вылетает.


Какие итерации - расшифрование разных файлов?
Сделать открытие хранилища один раз - не предлагать?


Я для теста расшифровываю один и тот же файл. Открывать хранилище один раз не подходит, да. В реальности файл будет появляться внезапно и держать хранилище всегда открытым не вариант. К тому же это костыли какие-то. Хранилище же должно нормально открываться и закрываться хоть сто пицот раз. Может я как-то не правильно его открываю? Просто обгуглился, примеров в интернете найти не могу, тем более под C#.



У меня не воспроизводилось. Пример минимальный можно...?

На сервере много сертификатов? Или ограниченное кол-во?
В хранилище идти, чтобы в итоге получить имя контейнера...
Можно и обойтись известным перечнем (серийный номер, контейнер)
Техническую поддержку оказываем тут
Наша база знаний
Offline esolomonov  
#48 Оставлено : 14 августа 2020 г. 21:03:41(UTC)
esolomonov

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

Группы: Участники
Зарегистрирован: 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
Offline esolomonov  
#49 Оставлено : 14 августа 2020 г. 21:46:07(UTC)
esolomonov

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

Группы: Участники
Зарегистрирован: 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 итерации... Пока работает :)
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
3 Страницы<123
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.