powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Правильно ли?
2 сообщений из 2, страница 1 из 1
Правильно ли?
    #32574776
Фотография APM
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача такая:
Реализовать некоторый механизм запрещающий создавать экземпляры класса одной сборки другими сборками не имеющими специальных атрибутов, а также попробовать обеспечить невозможность создания этих атрибутов посторонними лицами.

Идея решения:
Создать пару ключей rsa. Затем приватной частью ключа подписывать сборку с помощью специального приложения не включенного в дистрибутив, а паблик частью проверять подпись в конструкторе зашищаемого класса.

Ход работ:
1.
Итак генерим пару ключей и сохраняем в два файла public и private части.
Код: plaintext
1.
2.
3.
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider( 1024 );
			string xml = rsa.ToXmlString(false);
			string xml1 = rsa.ToXmlString(true);
2. Создаем атрибут (с областью применения сборка) для хранения подписи

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
[AttributeUsage(AttributeTargets.Assembly)]
	public class SignAttribute:Attribute 
	{
		
		private byte[] s;
		public byte[] S
		{
			get {return s;}
		}
			public SignAttribute(byte[] signed)
		{
			s=signed;
		}

	}

3. Делаем консольное приложение которым будем генерить подпись сборки (для примера на основании полного имени сборки), для удобства генерить будем в виде удобном для копирования в конструктор атрибута т.е. new byte[] {1,2...}
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
	static void Main(string[] args)
		{
			string filename= args[ 0 ];
	                 	Assembly a = Assembly.LoadFile(filename);
			string d=a.FullName;
			HashAlgorithm sha = new SHA1CryptoServiceProvider();
			RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
			string xml="<RSAKeyValue>Здесь приватный ключ</RSAKeyValue>";
			rsa.FromXmlString(xml);
			byte[] sign=rsa.SignData(d.ToByteArray(),sha);
			StringBuilder sb = new StringBuilder("new byte[] {");
			foreach( byte b in sign)
			{
				sb.Append(b);
				sb.Append(",");
			}
			sb.Append("}");
// далее sb.tostring() пишем в файл 

		}
	}


4. Пишем базовый класс для защищаемых классов (все они будут его потомками с единственной функцией проверяющей подписано ли приложение вызывающее его "как надо")
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
public class CryptProtect
	{
		protected bool IsSigned()
		{
			bool signed=true;
			Assembly a = Assembly.GetEntryAssembly();
			string s =a.FullName;
			try
			{
				SignAttribute atr = (SignAttribute) a.GetCustomAttributes(typeof(SignAttribute),false)[ 0 ];
				string xml ="<RSAKeyValue>Здесь публик ключ</RSAKeyValue>";
				RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
				rsa.FromXmlString(xml);
				SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
				signed =rsa.VerifyData(s.ToByteArray(),sha,atr.S);
			}
			catch
			{
				signed=false;
			}
			return signed;

			
			
		}
	}

5. Пишем для примера код защищаемого класса
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
public class MyPrivateClass:CryptProtect 
	{
		public Symetric()
		{
			if(!base.IsSigned())
                                            // Здесь генерим исключение и умираем

		}
	}

6. Делаем тестовую сборку вызывающую класс MyPrivateClass из защищаемой сборки, компилим его, прогоняем через наш консольный генератор подписи и в файл assemblyinfo.cs добавляем атрибут
Код: plaintext
1.
[assembly: Sign(new byte[] { 69 , 3 , 92 , 203 , 96 ,... и тд})]
Где массив сформирован нашим подписывателем.
Делаем также неподписанную версию этой сборки.

Запускаем - проверяем, все ok. Т.е. подписанная сборка класс создала, не подписываемая не смогла.

Теперь поанализируем:
Что же наваяли.
1.Итак, приватный ключ мы не распространяем он у нас в подписывающем консольном приложении т.е. есть маленькая надежда что злые юзеры не смогут сделать подпись другой сборки (хотя в нашем случае это и не надо т.к. злой юзер назовет свою сборку так же как и исходная и скопирует в него подписывающий атрибут), т.е. генерить подпись на имени сборки нельзя, итак первый вопрос опираясь на что генерить подпись?

2. В коде проверки подписи я использовал Assembly.GetEntryAssembly(); что естественно проверяет загруженную сборку "самого высокого уровня", наверное стоит переделать так чтоб можно было пройтись по всему стеку загруженных сборок и проверить у всех подписи, сходу не догадался как сделать, подскажите если кому не лень.

p.s.

Я вобщем-то ламер в вопросах криптографии и reflection, просто неожидано пришлось этим заниматься (что последние два часа и делаю), поэтому легко могу поверить что все что я тут нагородил полная фигня. И ни от чего не зашищает. Если это так то объясните мне пожалуйста мои ошибки, все когда то начинали.

Заранее спасибо.

Кому интересно полные исходные тексты могу выложить куда-нить.
...
Рейтинг: 0 / 0
Правильно ли?
    #32578654
Фотография B0rG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Посмотрите ветку Code Access Security в MSDN посвежее. Там есть встроенные механизмы контроля кто что может запускать, а кто что не может.

Ежели канал толстый и по английски говорите, то посмотрите вебкаст

http://msdn.microsoft.com/theshow/Episode031/default.asp

Там в общих чертах объясняют, че это такое и с чем его едят.

Когда разберетесь, то буду очень благодарен если чиркните пару строчек о том чего добились и как :)

Cheers
Pete
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Правильно ли?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]