Можно ли использовать строгое именование сборки для проверки автора сборки? - PullRequest
20 голосов
/ 15 декабря 2008

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

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

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

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

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

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

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

Ответы [ 4 ]

22 голосов
/ 15 декабря 2008

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

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

12 голосов
/ 15 декабря 2008

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

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

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

1 голос
/ 15 декабря 2008

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

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

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

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

0 голосов
/ 22 июля 2016

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

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

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

...