Можно ли использовать строгое именование сборки для проверки автора сборки?

Я читал соответствующую статью в MSDN, Strong-Named Assemblies и связанный с ним вопрос о переполнении стека, Проверка сборки на наличие строгого имени .

  1. В какой степени можно проверить сборку со строгим именем, чтобы избежать подделки?
  2. Можно ли использовать строгое именование для проверки автора сборки?

Первый вопрос возникает после прочтения статьи CSharp411 . Часто задаваемые вопросы по сборке .NET - Часть 3 - Строгие имена и подпись, где это упоминается среди других проблем использования строгих имен:

"Невозможно остановить полную замену. Сильные имена не могут помешать хакеру удалить подпись строгого имени, злонамеренно изменить вашу сборку, повторно подписать ее своим собственным ключом, а затем выдать свою сборку за ваш. "

Второй вопрос направлен на выявление различий между строгим именованием и другими схемами подписи, например, Authenticode. В той же статье MSDN упоминаются ранние состояния:

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

Пытаюсь ли я использовать строгое именование для чего-то большего, чем оно было создано? Было ли строгое именование создано только для того, чтобы избежать конфликта имен или нового типа «ада GAC DLL»?


person Pablo Marambio    schedule 15.12.2008    source источник


Ответы (5)


Когда вы подписываете сборку строгим именем на основе созданного вами закрытого ключа, это дает следующие преимущества:

  • Строгое имя гарантирует уникальность идентичности сборки, добавляя к сборке токен открытого ключа и цифровую подпись.
  • Строгое имя можно сопоставить с открытым ключом, чтобы доказать, что сборка исходит от издателя с этим открытым ключом и только от этого издателя.
  • Строгое имя обеспечивает строгую проверку целостности. Прохождение проверок безопасности .NET Framework гарантирует, что содержимое сборки не изменилось с момента ее последней сборки.

Можно ли использовать строгое именование для проверки автора сборки?

Да, как обсуждалось выше, строгое именование позволяет проверить последнего автора сборки. Но это не подтверждает подлинного автора. Если злоумышленник заменяет строгое имя вашей сборки, то все, что можно проверить, - это то, что вы не были последним автором сборки. Если он удалит строгое имя, проверка автора будет невозможна.

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

Следующий код C # проверяет, что злоумышленник не подделал токен открытого ключа, который был записан в вашу сборку, когда вы применили строгое имя. Он не защищает от взлома, но может обнаруживать некоторые типы взлома. Приведенный ниже метод принимает массив байтов, содержащий ваш токен открытого ключа, и сравнивает его с фактическим токеном сборки. Обратите внимание, что для того, чтобы этот метод был эффективным, выбранный вами обфускатор должен зашифровать строку, содержащую ваш токен открытого ключа, и расшифровывать ее только на лету, когда она используется. Также имейте в виду, что вам необходимо иметь разрешение FullTrust для работы этого кода, потому что он использует отражение под капотом.

// Check that public key token matches what's expected.
private static bool IsPublicTokenOkay_Check(byte [] tokenExpected)
{
    // Retrieve token from current assembly
    byte [] tokenCurrent = Assembly.GetExecutingAssembly().GetName().GetPublicKeyToken();

    // Check that lengths match
    if (tokenExpected.Length == tokenCurrent.Length)
    {
        // Check that token contents match
        for (int i = 0; i < tokenCurrent.Length; i++)
            if (tokenExpected[i] != tokenCurrent[i]) 
                return false;
    }
    else
    {
        return false;
    }
    return true;
}

Если вы работаете с версией .NET Framework до .NET 3.5 SP1, вы также можете принудительно проверить подпись строгого имени в случае, если сильное имя было удалено злоумышленником или проверка строгого имени была отключена в реестр. Следующий код демонстрирует вызов статического метода другого класса с именем NativeMethods. Здесь проверка будет принудительной.

// Check that this assembly has a strong name.
private bool IsStrongNameValid_Check()
{
    byte wasVerified = Convert.ToByte(false); 
     byte forceVerification = Convert.ToByte(true);
    string assemblyName = AppDomain.CurrentDomain.BaseDirectory + 
                          AppDomain.CurrentDomain.FriendlyName; 
    return NativeMethods.CheckSignature(assemblyName, 
                                        forceVerification, 
                                        ref wasVerified);
}

Фактическая проверка подписи выполняется с помощью P / Invoke, как показано ниже. Использование API StrongNameSignatureVerificationEx довольно запутано - достойное объяснение см. В эту запись в блоге.

// P/Invoke to check various security settings
// Using byte for arguments rather than bool, 
// because bool won't work on 64-bit Windows!
[DllImport("mscoree.dll", CharSet=CharSet.Unicode)]
private static extern bool StrongNameSignatureVerificationEx(string wszFilePath, 
                                                             byte fForceVerification, 
                                                             ref byte pfWasVerified);

// Private constructor because this type has no non-static members
private NativeMethods()
{
}

public static bool CheckSignature(string assemblyName, 
                                  byte forceVerification, 
                                  ref byte wasVerified)
{
    return StrongNameSignatureVerificationEx(assemblyName, 
                                             forceVerification, 
                                             ref wasVerified );
}

Обратите внимание, что это не будет работать по умолчанию для приложений, использующих .NET 3.5 SP1 или выше, у которых есть функция обхода строгого имени. Эту функцию можно отключить для вашего приложения, добавив параметр в его файл конфигурации. Но, конечно, любой злоумышленник с доступом для чтения / записи к этому файлу конфигурации может изменить ваше решение.

person HTTP 410    schedule 15.12.2008
comment
Спасибо! Отличный пример. Какие виды взлома будут пропущены / обойдены этой проверкой? - person Pablo Marambio; 16.12.2008
comment
Этот код не обнаружит ситуацию, когда злоумышленник изменил вашу копию токена открытого ключа, чтобы она соответствовала его собственному открытому ключу. И, конечно же, он не может обнаружить подделку, когда сам код не запускается. - person HTTP 410; 16.12.2008
comment
@RoadWarrior: Отличный материал. Мне придется снова об этом подумать. - person Hamish Smith; 16.12.2008
comment
Для этого требуется .NET 3.5. Как можно адаптировать этот код для проверки подписи строгого имени на компьютере под управлением Windows 8 с .NET 4 и новее? - person Marcus; 13.01.2014
comment
@ Игорь, я обновил свой ответ, чтобы ответить на твой вопрос. - person HTTP 410; 14.01.2014
comment
Ожидаемая проверка токена открытого ключа + StrongNameSignatureVerificationEx с wasVerified должна иметь значение true. Это работает даже с сильным обходом имен. MSDN сообщает: pfWasVerified также имеет значение false, если проверка прошла успешно из-за настроек реестра. - person Martin.Martinsson; 22.10.2020

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

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

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

person mmx    schedule 15.12.2008
comment
Но проверка, которая проверяет, является ли открытый ключ тем, который, как вы знаете, действителен, должна выполняться вручную. Не так ли? - person Pablo Marambio; 15.12.2008
comment
Да, мы теоретически говорим об этом факте. На практике не рекомендуется использовать строгое имя для этих целей. В конце концов, это сильное имя, а не сильная подпись. Но теоретически это возможный и довольно безопасный способ выполнить то, что я сказал, прямо как подпись GPG или около того ... - person mmx; 15.12.2008

Я думаю, что строгие имена полезны для управления версиями и могут использоваться, чтобы помочь с установкой уровней доверия для безопасности доступа к коду Edit: , но вы не можете использовать их для проверки того, что сборка создана кем-то доверенный или конкретным автором. См. комментарий от @RoadWarrior и ответ @ RoadWarrior на этот вопрос.

Сильное именование сборки не делает ее защищенной от несанкционированного доступа.
Изменить: См. Комментарии от @RoadWarrior и @divo. Если ваше приложение проверяет исходный закрытый ключ от автора сборки и требует проверки строгого имени, мое утверждение неверно. Однако, если злоумышленник имеет доступ ко всем сборкам в вашем приложении и / или вы используете стандартную проверку строгого имени, предоставляемую CLR бесплатно, то я согласен с тем, что я сказал.

Это может быть нарушено решительным злоумышленником .

Я прочитал person Hamish Smith    schedule 15.12.2008

comment
›Сильное обозначение сборки не делает ее защищенной от несанкционированного доступа. ‹Я думаю, что это неправда, когда вы знаете (и проверяете) открытый ключ оригинального автора, потому что измененная сборка будет иметь другую подпись. Надстройки надежного MS-Office, написанные на .NET, полагаются на этот факт, кстати. - person Dirk Vollmar; 16.12.2008
comment
Хэмиш, вы можете использовать строгое имя, чтобы убедиться, что сборка была создана определенным автором, потому что, хотя злоумышленник может вмешаться в сборку, он не может повторно использовать строгое имя исходной сборки. . - person HTTP 410; 16.12.2008

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

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

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

person Iftikhar Ali    schedule 22.07.2016

Если вы хотите проверить целостность сборки, вам необходимо выполнить проверку токена открытого ключа (см. Ответ HTTP 410 выше) и проверку с помощью StrongNameSignatureVerificationEx (https://docs.microsoft.com/de-de/dotnet/framework/unmanaged-api/strong-naming/strongnamesignatureverificationex-function). Оба результата StrongNameSignatureVerificationEx и выходной параметр pfWasVerified должны быть истинными. Просто используйте один файл ключа подписи (.snk) для всех ваших сборок.

Лучше был бы хороший обфускатор сборки .NET, такой как BabelFor.Net или около того. Многие из них имеют встроенную защиту от взлома.

Ваше здоровье

person Martin.Martinsson    schedule 22.10.2020