Как программно проверить сборку, подписанную с помощью специального сертификата?

В моем сценарии есть одна программа (exe), которая запустит другие программы, если их найдет в определенной папке. Я хочу, чтобы он только запускал программы, которые подписываются с нашим Корпоративным сертификатом (Verisign approved и т.д.). По сути, он будет запускать программы только с тем же сертификатом, что и сам. Я не хочу отправлять сам сертификат.

Я искал веб-пространство и пространство имен системы и не нашел четкого примера, который считывает данные сертификата из файла, а также проверяет его и может проверять на другой файл. Самое близкое, что я нашел, это Signtool, и эта проверка в отдельном exe является менее точным. Я знаю, что материал Strong Naming не поможет, потому что файл с цифровой подписью отличается тем, что объясняется здесь (http://blog.codingoutloud.com/2010/03/13/three-ways-to-tell-whether-an-assembly- dl-is-strong-named/) Также некоторые другие примеры в SO показывают шифрование и проверку необработанных данных, но не сборку, в которой она каким-то образом упакована.

Любые идеи или предложения?

Ответ 1

Здесь сообщение в блоге с образцами кода о том, как проверить подписывание сборок:
http://blogs.msdn.com/b/shawnfa/archive/2004/06/07/150378.aspx

Пример кода в конце показывает, как проверить, была ли сборка подписана Microsoft или нет - вы можете сделать то же самое, получив токен сертификата для сертификатов вашей компании.

Обновление: пользователь @Saber отредактировал это со следующим обновлением, но это обновление было отклонено другими. Тем не менее, это очень полезный совет, поэтому я переношу его/ее редактирование, так как SO не разрешит мне его одобрить:

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

Ответ 2

Существуют две технологии подписи для сборников .NET: strongnaming и Authenticode (аутентификация используется для подписи PE и некоторых других файлов, а не только для сборки .NET). Они используются для разных целей. Сертификаты используются в Authenticode только для аутентификации автора. Strongnaming не аутентифицирует автора вообще.

Помимо проверки подписи, сертификат должен быть проверен, чтобы гарантировать, что он был выпущен для данного автора. Правильная проверка является сложной процедурой, которая включает CRL (список отзыва сертификатов) и OCSP (статус онлайн-сертификата).

Для выполнения проверки подлинности подписи Authenticode необходим компонент проверки подлинности. Один из вариантов заключается в использовании пакета PKIBlackbox нашего продукта SecureBlackbox. Пакет включает проверку подлинности аутентификации, а также полные механизмы проверки сертификатов.

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

Ответ 3

Здесь вы можете попробовать три варианта.

1) Первый использует загрузку сборки, как здесь:

Assembly myDll =
    Assembly.Load("myDll, Version=1.0.0.1, Culture=neutral, PublicKeyToken=9b35aa32c18d4fb1");

Вы можете распечатать шестнадцатеричный формат открытого ключа и токена открытого ключа для конкретной сборки, используя следующую команду Strong Name (Sn.exe):

sn -Tp <assembly>

Если у вас есть файл открытого ключа, вы можете использовать следующую команду (обратите внимание на разницу в случае опции командной строки):

sn -Tp <assembly>

2) Здесь упоминается второй . И используйте p/Invoke для такой проблемы.

3) Также существует третий, более гибкий и более сложный способ для этого. Это Политика привязки. Вы можете принять это во внимание в случае, если вам необходимо предоставить обновления для уже развернутого приложения. Когда появляется новая версия общего компонента, доступ к которой может получить ваше приложение, файл политики приложения позволит вам предоставить эти преимущества без повторной компиляции или замены существующих установок.

Подробнее об этой функции вы можете найти здесь:

http://msdn.microsoft.com/en-us/library/aa309359%28v=vs.71%29.aspx

http://ondotnet.com/pub/a/dotnet/2003/03/17/bindingpolicy.html

Ответ 4

Я считаю, что есть способ использовать сильное имя для цели "Доверие". Я понимаю, что Microsoft рекомендует только сильное имя, чтобы содержимое сборки не было изменено, и предлагает использовать для аутентификации "Authenticode".

Но если приложение-загрузчик (приложение, которое загружает эти сборки/программы) поддерживает зашифрованный список "сборок", который он может загрузить; не решит ли проблема "доверия"?

Например, загрузчик пакетов может поддерживать имя сборки с открытыми ключами и загружает сборку/программу через полное имя сборки?

<PackageHandlers>
  <PackageHandler>
    <Package type="Package1" assembyName="SomeAssembly" publickey="d45755dbb8b44e59" />
  </PackageHandler>
</PackageHandlers>