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

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

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

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

"Не Удается Остановить Полную Замену. строгие имена не могут помешать хакеру удалить подпись строгого имени, злонамеренно изменить вашу сборку, повторно подписать ее своим ключом, а затем передать свою сборку как вашу."

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

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

Я пытаюсь использовать сильное именование для гораздо большего, чем оно было создано? Было сильное именование создано только для того, чтобы избежать столкновений имен или нового вида "GAC DLL Hell"?

4 ответов


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

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

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

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

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

следующий код C# проверяет, что злоумышленник не подделал маркер открытого ключа, который был записан в сборку при применении строгого имени. Это не избегайте вмешательства, но он может обнаружить некоторые типы вмешательства. Ниже метод принимает массив байтов, содержащий маркер открытого ключа и сравнивает его с фактическим маркера ассамблеи. Обратите внимание, что для того, чтобы этот метод был эффективным, ваш obfuscator выбора должен зашифровать строку, содержащую маркер открытого ключа, и только расшифровать его на лету, как он используется. И также имейте в виду, что для работы этого кода необходимо иметь разрешение 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, как показано ниже. Использование StrongNameSignatureVerificationEx API довольно запутанный - для приличного объяснения см. эта запись в блоге.

// 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 или выше, который имеет функция обхода сильного имени. Это возможно отключить эту функцию для вашего приложения, добавив параметр в его конфигурационный файл. Но, конечно, любой злоумышленник с доступом для чтения/записи в этот файл конфигурации может отменить ваше решение.


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

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

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


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

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

Это может быть разрушено решительный нападающий.

Я прочитала a обсуждение некоторое время назад о сильных именах и безопасности, которые заставили меня поверить, что для сборок, которые мы производим, authenticode был лучшей гарантией для наших клиентов, что сборка пришла из надежного источника.


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

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

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