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

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

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

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

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

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

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

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

Ответ 1

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

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

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

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

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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

Ответ 4

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

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

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