Я всегда понимал, что целью подписания сборки является проверка во время выполнения, чтобы гарантировать, что обновления кода происходят из надежного источника. Фактически они пытаются избежать такого сценария:
Я покупаю библиотеку шифрования у компании A, вскоре после этого компания B получает мои данные электронной почты и отправляет мне бесплатное обновление сборки, выдавая себя за серьезное исправление ошибки безопасности у компании A, когда она действительно внедряет скрытый метод в мой код, который отправляет все данные, которые я пытался зашифровать, на серверы компании B. Предполагая, что я идиот и слепо добавляю эту новую dll в каталог bin моего приложения, тот факт, что он не был подписан тем же закрытым ключом, что и старая версия, будет обнаружен во время выполнения, что вызовет исключение и защитит мои данные.
Итак, я не вижу причин, по которым вы бы опубликовали открытый ключ за пределами сборки, поскольку он не должен гарантировать, что исходный файл получен от определенного поставщика, только что все последующие версии поступают из того же места, что и первый.
Википедия говорит примерно то же самое (только в значительно меньшем количестве слов).
Отредактировано для добавления дополнительной информации, чтобы сделать это более понятным ...
Я думаю, что прежде всего необходимо уточнить, что пары открытых и закрытых ключей уникальны. Это означает, что знание открытого ключа недостаточно для того, чтобы перестроить сборку так, чтобы она прошла те же проверки хешей.
Итак, пользователь Z, использующий библиотеку шифрования из компании А, которая находится в папке его приложений. Для этого он ссылается на DLL следующим образом:
Encryption, Version=1.0.0.0, Culture=neutral, PublicKeyToken=bcd6707151635d07"
Цель открытого ключа - предоставить нам три преимущества , с которыми я буду обращаться по одному за раз.
Во-первых, он предоставляет уникальное имя для сборки - это не дает нам дополнительной безопасности, но останавливает dll Hell в стиле C, когда две разные компании могут выпустить две разные библиотеки под названием Encyption версии 1.0.0.0, и вы не сможете храните их в одном и том же каталоге, поскольку их невозможно дифференцировать.
Во-вторых, это предотвращает сценарий, который я обрисовал в своем первоначальном посте. Компания B не может создать другую версию библиотеки Encryption, которая также является версией 1.0.0.0 и имеет тот же открытый ключ (чтобы полное имя совпадало, и вы вызывали их код вместо компании A). Они не могут этого сделать, потому что если их открытый ключ совпадает, то закрытый ключ также должен совпадать (поскольку каждая пара уникальна). Единственный способ получить закрытый ключ - это поставить под угрозу безопасность компании А.
Наконец, он обеспечивает целостность файла (либо изменен в результате повреждения или внедрения вредоносного кода). DLL хэшируется во время выполнения (когда оно является приватным и находится в папке bin приложения) или во время установки (когда вы помещаете его в GAC) с использованием открытого ключа, и этот хэш сравнивается с хешем, который был зашифрован приватным ключ и хранится в сборке. Эта страница содержит некоторые диаграммы и более подробную информацию. Еще раз, единственный способ подделать этот хеш - это узнать секретный ключ.
Итак, чтобы охватить конкретный сценарий, который я описал выше, сделайте вид, что я Компания B, пытающаяся предоставить Пользователю Z вредоносную версию DLL шифрования. Моя первая попытка - просто создать свою собственную dll с именем Encryption и Version 1.0.0.0 и подписать ее с помощью своей собственной пары ключей. К сожалению, я не могу изменить ссылочный код в приложении пользователя Z, поэтому он не проходит проверку полного имени и не загружается. «Хорошо, - говорит я, закручивая усы, - я просто изменю открытый ключ моей сборки, чтобы он соответствовал ключу компании А». Как только я это сделаю, проверка имени проходит, но проверка хеша завершится неудачей, потому что приложение пользователя Z не сможет расшифровать хэш, сохраненный в сборке (которая была зашифрована с помощью закрытого ключа компании B) с помощью открытого ключа (Company А), который был поставлен. Следовательно, единственный способ для компании B создать библиотеку, которая претендует на звание компании A, - это узнать закрытый ключ компании A. Ни одна из этих проверок безопасности не зависит от компании А, публикующей открытый ключ где-либо еще, кроме первоначального выпуска сборки.
Обратите внимание, что все эти функции не гарантируют (и не утверждают, что гарантируют), что исходная сборка была получена от компании A, которая обрабатывается другими системами, такими как Verisign или Microsoft * Служба 1037 * Authenticode гарантирует, что только после ссылки на сборку только компания А может внести изменения в этот код.