Какова роль токена открытого ключа?

79

Какова роль токена открытого ключа? Участвует ли он в расшифровке подписанного хэша. Почему в GAC так много сборок от Microsoft с одним и тем же токеном открытого ключа?

программное обеспечение
источник
1
@Bombe, расшифровать хеш подписи было бы правильно, всего 1 ошибка.
Хенк Холтерман,
См. Также stackoverflow.com/q/573079/284795
Colonel Panic
Если вы знакомы с SSH или PGP, это то, что вы называете отпечатком пальца, т.е. сокращенная версия открытого ключа, которую легче проверить на глаз.
Colonel Panic

Ответы:

160

Какова роль токена открытого ключа?

Токен открытого ключа - это небольшое число, которое является удобным «токеном», представляющим открытый ключ. Открытые ключи довольно длинные; цель токена открытого ключа - дать вам возможность ссылаться на ключи, не называя ключ целиком. Примерно так же сказать «Властелин колец» - это пять слов, которые представляют собой роман на полмиллиона слов. Было бы довольно неудобно, если бы каждый раз, когда вы захотели об этом поговорить, вам приходилось произносить эти полмиллиона слов.

Участвует ли он в расшифровке подписанного хэша?

Нет. Токен открытого ключа не содержит "информации". Это просто число, представляющее открытый ключ. Сам по себе это не открытый ключ.

почему так много сборок от Microsoft с одним и тем же токеном открытого ключа?

Потому что все они были подписаны одним и тем же закрытым ключом - закрытым ключом Microsoft - и поэтому все проверены одним и тем же открытым ключом, и, следовательно, все имеют один и тот же токен открытого ключа.

Эрик Липперт
источник
3
Какой четкий и идеальный ответ, Эрик!
Адитья Бокаде, 06
@Ammar с помощью кода проверьте Assembly.FullNameсвойство, чтобы получить его с помощью инструментов командной строки, см. Этот ответ
Скотт Чемберлен,
14

Из Википедии

«Токен открытого ключа используется для того, чтобы сделать имя сборки уникальным. Таким образом, две сборки со строгими именами могут иметь одно и то же имя PE-файла, но .NET распознает их как разные сборки. Файловая система Windows (FAT32 и NTFS) распознает только Имя PE-файла, поэтому две сборки с одинаковым именем PE-файла (но с разной культурой, версией или токеном открытого ключа) не могут существовать в одной папке Windows. Для решения этой проблемы .NET вводит нечто, называемое GAC (Global Assembly Cache), которое является рассматривается как отдельная папка .NET CLR, но фактически реализована с использованием вложенных папок NTFS (или FAT32).

Чтобы предотвратить атаки с подменой, когда взломщик пытается выдать сборку за что-то еще, сборка подписывается закрытым ключом. Разработчик предполагаемой сборки хранит закрытый ключ в секрете, поэтому взломщик не может получить к нему доступ или просто угадать его. Таким образом, взломщик не может заставить свою сборку олицетворять что-то еще, не имея возможности правильно подписать ее после изменения. Подписание сборки включает взятие хэша важных частей сборки и последующее шифрование хэша с помощью закрытого ключа. Подписанный хэш сохраняется в сборке вместе с открытым ключом. Открытый ключ расшифрует подписанный хэш.Когда CLR загружает сборку со строгим именем, она генерирует хэш из сборки, а затем сравнивает его с расшифрованным хешем. Если сравнение прошло успешно, это означает, что открытый ключ в файле (и, следовательно, токен открытого ключа) связан с закрытым ключом, используемым для подписи сборки. Это будет означать, что открытый ключ в сборке является открытым ключом издателя сборки, и, следовательно, атака с использованием спуфинга предотвращена. "

ризм
источник
6

Хеш - это своего рода «отпечаток пальца». Он подписан с использованием закрытого ключа, принадлежащего (и известного только ему) подписывающей стороны. Если вам известен открытый ключ подписывающей стороны, вы можете проверить, действительно ли хэш принадлежит подписывающей стороне и, следовательно, действительно ли данные / файл исходят от подписывающей стороны (и не изменились). Одинаковые открытые ключи для некоторых файлов в GAC означают «все подписаны одним и тем же подписывающим лицом».

ур.
источник
Значит, токен - это просто индикатор используемого ключа паба? Он не участвует напрямую в шифровании / дешифровании
Softwarematter
5

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

Каждая компания (или отдел) должна использовать только 1 пару ключей, поэтому вы видите группы идентичных PKT в GAC.

Хенк Холтерман
источник
1

Я хотел бы добавить к предыдущим ответам (особенно к тому, который содержит цитату из Википедии), что строгое именование с помощью открытого / закрытого ключа не защищает вас от получения измененной сборки и не препятствует вмешательству кого-либо в ваши сборки.

Во-первых , строгое имя не гарантирует, что сборке можно доверять. У вас есть только открытый ключ / токен открытого ключа, но вы не знаете человека, который его подписал (кроме случаев, когда они каким-то образом заявляют, что владеют открытым ключом сборки).

Например, хакер может взять вашу сборку, удалить из нее строгое имя (есть инструменты, которые это делают) и подписать ее собственным строгим именем. Для траста существует другой вид цифровой подписи кода сертификатом. Это связано с проверкой вас и вашей компании третьей стороной и не является бесплатным. Ознакомьтесь с технологией Authenticode:

https://msdn.microsoft.com/en-us/library/ms537359(v=vs.85).aspx

Во-вторых , в следующем обсуждении кратко описан метод атаки методом перебора, чтобы получить пару открытого / закрытого ключей с одним и тем же токеном открытого ключа, который будет генерировать тот же хеш для подделанной сборки:

https://groups.google.com/forum/?hl=en#!topic/microsoft.public.dotnet.security/Jo6PqypxJN8

Я должен отметить, что эту проблему можно было решить с помощью расширенного строгого именования https://docs.microsoft.com/en-us/dotnet/framework/app-domains/enhanced-strong-naming

В обсуждении также упоминалась ошибка, которая позволяла пропустить проверку сборки и загрузить измененную сборку во время выполнения. Подробное исследование здесь, ошибка была исправлена ​​в более поздних версиях .Net framework (поэтому ошибка присутствует в старой .Net 1):

http://www.grimes.nildram.co.uk/workshops/fusionWSCrackThree.htm

В-третьих , запуск .Net 3.5 sp1 для увеличения производительности загрузки сборок не проверяется по умолчанию для сборок с полным доверием.

https://docs.microsoft.com/en-us/dotnet/framework/app-domains/how-to-disable-the-strong-name-bypass-feature

Условие для сборок: https://blogs.msdn.microsoft.com/shawnfa/2008/05/14/strong-name-bypass/

Обсуждение этого вопроса в Stack Overflow: проверяются ли когда-либо подписанные сборки .net при загрузке, чтобы убедиться, что они не были изменены?

Насколько я понимаю, это означает, что сборка не хешируется при загрузке, чтобы проверить, не

Наконец , я хотел бы упомянуть, что ведутся споры о преимуществах и недостатках строгого именования, поскольку они требуют, чтобы вы указали версию сборки. Microsoft удаляет строгие имена из некоторых своих продуктов: https://www.pedrolamas.com/2016/03/01/still-strong-naming-your-assemblies-you-do-know-its-2016-right/

В заключении, Я хотел резюмировать все упомянутые моменты. Когда я столкнулся с сильным именованием, MSDN и Википедия ошиблись, что они могут обеспечить некоторую защиту сборкам. Я подумал "Круто", и сильное именование осталось в моей памяти как механизм защиты. До этого момента мне приходилось думать о безопасности моего файла snk с закрытым ключом, а потом мой коллега сказал мне, что это не так уж и круто. Итак, я провел небольшое исследование. Первое, что я узнал, это то, что строгое имя не означает доверия, для этого нужно использовать сертификат. Тем не менее, я думал, что если я сохраню свой закрытый ключ в безопасности, то измененная сборка не будет подписана мной, а это означает, что если кто-то изменит мою сборку, он также должен будет изменить знак, и измененная сборка не будет загружена CLR. Теперь я не Не думаю, что это гарантирует сильное именование. Так что полагаться на него стоит только для гарантии уникальности сборки.

PS. Извините за длинный пост с большим количеством ссылок.

СЕНЯ
источник