В интернете и книгах достаточно много информации по этой теме. Но достаточно трудно найти ресурс, где бы чётко и доступным языком были описаны основные моменты. И так, в этом посте я постараюсь информацию более-менее структурировать.
.NET Framework поддерживает 2-а вида сборок (следующая терминология придумана исключительно Дж. Рихтером и не встречается в документации по .NET Framework):
Оба вида сборок имеют идентичную структуру (заголовка PE32(+), CLR-заголовка, метаданных, таблиц декларации, IL-кода).
Сборки отличатся лишь тем, что вторые подписаны при помощи пары ключей, позволяющих уникально идентифицировать сборку, обеспечить её безопасность, управлять её версиями, развёртывать её в любом месте на жёстком диске (или даже в интернете).
Развёртывание сборки может быть закрытым и глобальным. Глобальное развёртывание можно осуществить только со сборками со строгими именами, т.е. такие сборки можно поместить в каталог, который CLR проверяет при поиске сборки (c:\Windows\assembly\ - скрытая папка).
Если сборка с нестрогим именем, то CLR всегда игнорирует номер версии (!), а при поиске сборок использует лишь идентификатор региональных стандартов и ищет её в каталоге приложения.
Если сборка со строгим именем, то CLR при поиске сборок использует как идентификатор региональных стандартов, так и номер версии. Сборка также подписана при помощи закрытого ключа издателя.
Приступим к созданию сборки со строгим именем. Создадим, для начала, на диске С директорию "assem".
Теперь необходимо сгенерировать ключи с помощью утилиты Strong Name (SN.exe), поставляемой в составе .NET Framework SDK. Для этого открывает утилиту Visual Studio Command Prompt, поставляемой в составе Visual Studio и пишем следующую команду:
Для удаления ключа из контейнера CSP, надо ввести команду(сие делать не надо):
SN –d MyKey
Если всё правильно ввели, то получим сообщение:
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyKeyFile(@"C:\assem\key.snk")]
[assembly: AssemblyKeyName("MyKey")]
[assembly: AssemblyDelaySign(true)]
Затем в Visual Studio выбираем Project – Properties…Откроем вкладку Signing и поставим галочку в чек бокс Sign the assembly. В раскрывающемся списке поля Choose a strong name key file, выберем <Browse> и в открывшемся диалоговом окне выбора файлов ключей перейдем в нашу директорию C:\assem и выберем файл ключа key.snk.
Манифест (декларация) – это своего рода, личный паспорт сборки. Манифест отвечает за хранение следующих данных:
- информация о сборке, а именно имя, версия, контрольная сумма, открытый криптографический ключ;
В теории, теория и практика неразделимы. На практике это не так (Yoggi Berra).
.NET Framework поддерживает 2-а вида сборок (следующая терминология придумана исключительно Дж. Рихтером и не встречается в документации по .NET Framework):
- с нестрогими именами (weakly named assemblies);
- со строгими именами (strongly named assemblies).
Оба вида сборок имеют идентичную структуру (заголовка PE32(+), CLR-заголовка, метаданных, таблиц декларации, IL-кода).
Сборки отличатся лишь тем, что вторые подписаны при помощи пары ключей, позволяющих уникально идентифицировать сборку, обеспечить её безопасность, управлять её версиями, развёртывать её в любом месте на жёстком диске (или даже в интернете).
Развёртывание сборки может быть закрытым и глобальным. Глобальное развёртывание можно осуществить только со сборками со строгими именами, т.е. такие сборки можно поместить в каталог, который CLR проверяет при поиске сборки (c:\Windows\assembly\ - скрытая папка).
Если сборка с нестрогим именем, то CLR всегда игнорирует номер версии (!), а при поиске сборок использует лишь идентификатор региональных стандартов и ищет её в каталоге приложения.
Если сборка со строгим именем, то CLR при поиске сборок использует как идентификатор региональных стандартов, так и номер версии. Сборка также подписана при помощи закрытого ключа издателя.
Приступим к созданию сборки со строгим именем. Создадим, для начала, на диске С директорию "assem".
Теперь необходимо сгенерировать ключи с помощью утилиты Strong Name (SN.exe), поставляемой в составе .NET Framework SDK. Для этого открывает утилиту Visual Studio Command Prompt, поставляемой в составе Visual Studio и пишем следующую команду:
SN -k C:\assem\key.snk
Т.е. пара ключей уже готова. Эта команда заставит SN.exe создать файл key.snk, содержащий открытый и закрытый ключи в двоичном формате, поместить его по указанному адресу. Числа, образующие открытый ключ, очень велики. Чтобы посмотреть открытый ключ и узнать его маркер введём следующую команду в Command Prompt:
SN -tp C:\assem\key.snk
Если мы хотим увидеть только маркер открытого ключа, то:
SN -t C:\assem\key.snk
Вместе с тем невозможно заставить SN.exe отобразить закрытый ключ. Маркер - это 64- разрядный хэш открытого ключа (контрольная сумма). Маркер был введен для того чтобы сократить запись строго имени сборки. Он по умолчанию рассчитывается при помощи алгоритма SHA-1 (Secure Hash Algorithm).
Теперь надо установить наш ключ в CSP (Cryptographic Service Provider) командой в Command Prompt:
SN -i C:\assem\key.snk MyKey
Если всё правильно ввели, то получим сообщение:
Microsoft (R) .NET Framework Strong Name Utility Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Key pair installed into ‘MyKey’
Copyright (c) Microsoft Corporation. All rights reserved.
Key pair installed into ‘MyKey’
Для удаления ключа из контейнера CSP, надо ввести команду(сие делать не надо):
SN –d MyKey
Если всё правильно ввели, то получим сообщение:
Microsoft (R) .NET Framework Strong Name Utility Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Container ‘MyKey’ deleted
Извлекаем открытый ключ из пары ключей хранящейся в CSP, с помощью команды:
SN -pc MyKey C:\assem\keyPublicKey.snk
Если всё правильно ввели, то получим сообщение:
Microsoft (R) .NET Framework Strong Name Utility Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Public key written to C:\assem\keyPublicKey.snk
Теперь в нашем проектеTest, который находится в директории C:\assem, в модуль AssemblyInfo.cs, добавим следующий код (!):Copyright (c) Microsoft Corporation. All rights reserved.
Public key written to C:\assem\keyPublicKey.snk
[assembly: AssemblyCulture("ru-Ru")]
[assembly: AssemblyVersion("1.0.0.0")][assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyKeyFile(@"C:\assem\key.snk")]
[assembly: AssemblyKeyName("MyKey")]
[assembly: AssemblyDelaySign(true)]
Затем в Visual Studio выбираем Project – Properties…Откроем вкладку Signing и поставим галочку в чек бокс Sign the assembly. В раскрывающемся списке поля Choose a strong name key file, выберем <Browse> и в открывшемся диалоговом окне выбора файлов ключей перейдем в нашу директорию C:\assem и выберем файл ключа key.snk.
Или можно выбрать <New> тогда среда разработки сама создаст новый файл ключа с помощью утилиты sn.exe.
После этого нажмем Ctrl+S и перейдем в Solution Explorer, как видно там появился файл key.snk.
После этого нажмем Ctrl+S и перейдем в Solution Explorer, как видно там появился файл key.snk.
Завершаем подпись сборки, вводим команду уже в Command Prompt (регистр учитывается):
SN-Rc C:\assem\Test\Test\bin\Debug\Test.dll MyKey
Получим сообщение:
Public key token is c2061d94b81f5e18
Вот и всё. Наша сборка со строгим именем готова и можно развернуть её глобально.
Теперь очень важный момент! После подписания сборки модифицировать её будет нельзя, т.к. хэш станет недействительным.
Что же происходит когда одна сборка вызывает другую сборку имеющую строгое имя? А происходит следующее, исполняющая среда сравнивает ключ, хранящийся в манифесте ссылающейся сборки, с ключом, используемым для генерирования строгого имени для сборки, на которую указывает ссылка. Если проверки безопасности .Net Framework и привязка проходят успешно, ссылающаяся сборка получает гарантии, что сборка, на которую она ссылается, не была изменена или подделана.
Microsoft (R) .NET Framework Strong Name Utility Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Assembly ‘C:\MyAssembly\MyStrongNameAssembly.dll’ successfully re-signed
Теперь проверим подлинна ли наша сборка, введем команду:Copyright (c) Microsoft Corporation. All rights reserved.
Assembly ‘C:\MyAssembly\MyStrongNameAssembly.dll’ successfully re-signed
SN-v C:\assem\Test\Test\bin\debug\Test.dll
Получим сообщение:
Copyright (c) Microsoft Corporation. All rights reserved.
Assembly 'C:\assem\Test\Test\bin\Debug\Test.dll' is valid
Далее введем команду чтобы просмотреть открытый ключ и его маркер:Assembly 'C:\assem\Test\Test\bin\Debug\Test.dll' is valid
sn -Tp C:\assem\Test\Test\bin\Debug\Test.dll
Если правильно ввели команду, получите следующее сообщение(примерно):
Microsoft (R) .NET Framework Strong Name Utility Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.
Public key is
Copyright (c) Microsoft Corporation. All rights reserved.
Public key is
002400000480000094000000060200000024000052534131000400000100010047bd
9fc66d2bcc829f1bdd7e819b93e5879f3c00f1ee3a7df035bd590f1fe7d3e388aaa6
5f9aa395868e8b76b839706da7f7d640cc9028aa1b9e989bd36ccfe9a4c599ac5339
23e883103396883a782bf428eb28e06ee10067742e11a2161793d89b228954fa36bf
0a2df410a1a33008553fb94e7458ea9e38a1ee0b0d70a8dc
Public key token is c2061d94b81f5e18
Теперь очень важный момент! После подписания сборки модифицировать её будет нельзя, т.к. хэш станет недействительным.
Что же происходит когда одна сборка вызывает другую сборку имеющую строгое имя? А происходит следующее, исполняющая среда сравнивает ключ, хранящийся в манифесте ссылающейся сборки, с ключом, используемым для генерирования строгого имени для сборки, на которую указывает ссылка. Если проверки безопасности .Net Framework и привязка проходят успешно, ссылающаяся сборка получает гарантии, что сборка, на которую она ссылается, не была изменена или подделана.
Манифест (декларация) – это своего рода, личный паспорт сборки. Манифест отвечает за хранение следующих данных:
- информация о сборке, а именно имя, версия, контрольная сумма, открытый криптографический ключ;
- список файлов, составляющих сборку, в случае, если она является много файловой;
- список сборок, необходимых для функционирования этой сборки;
В теории, теория и практика неразделимы. На практике это не так (Yoggi Berra).
Спасибо, описание то что надо!
ОтветитьУдалитьСпасибо, замечательно!
ОтветитьУдалить