Почему рекомендуется включать закрытый ключ, используемый для подписи сборки, в репозитории с открытым исходным кодом?
Согласно MSDN, при разработке программного обеспечения с открытым исходным кодом рекомендуется включать как закрытые, так и открытые ключи, используемые для сборок со строгими именами, в систему управления с открытым исходным кодом:
Если вы являетесь разработчиком программного обеспечения с открытым исходным кодом и хотите получить преимущества идентификации в сборке со строгим именем, рассмотрите возможность проверки закрытого ключа, связанного со сборкой, в вашей системе управления версиями.
Это то, что меня сильно смущает. Делать закрытый ключ открытым? Разве в этом случае не будет побеждена вся цель и безопасность асимметричной криптографии?
Я вижу в той же статье эту заметку:
Не полагайтесь на строгие имена для обеспечения безопасности. Они предоставляют только уникальную личность.
Это не поможет уменьшить мою путаницу. Зачем тогда использовать пару закрытый-открытый ключ, если безопасность не является целью? Является ли механизм строгих имен в.NET ненадлежащим образом, использующим пары закрытых и открытых ключей? Я предполагаю, что я что-то упускаю или неправильно понимаю.
2 ответа
Сильная подпись не для безопасности, она гарантирует уникальность. Это так, если два человека делают Foo.dll v1.0.0.0
у вас есть способ отличить их в GAC.
Если у вас есть библиотека с открытым исходным кодом, и вы хотите, чтобы ваш конечный пользователь MyOpenSource.dll v1.0.0.0
быть в состоянии заменить замену MyOpenSource.dll v1.0.0.0
тогда и копия пользователя, и официальная копия должны быть подписаны одним и тем же ключом (или оба должны быть вообще не подписаны). Вот почему вы хотели бы распространять его.
Ключ строгого имени не для того, чтобы сказать: "Это официальная, неизмененная копия MyOpenSource.dll
", это то, для чего используется подпись Authenticode. Это только для предотвращения конфликтов имен от разных издателей.
Я не согласен с тем, что подписание ваших собраний не имеет никакого отношения к безопасности. Да, он используется для идентификации сборки. И по умолчанию подпись НЕ применяется. Так что в этом отношении, да, безопасность напрямую не зависит только от подписания. Однако вы МОЖЕТЕ использовать свою пару ключей для обеспечения проверки подписи без необходимости выдавать сертификат CA. Однако, чтобы сделать это, вы должны P/ вызвать эту функцию:
Imports System.Runtime.InteropServices
Friend Class NativeMethods
<DllImport("mscoree.dll", CharSet:=CharSet.Unicode)> _
Public Shared Function StrongNameSignatureVerificationEx(wszFilePath As String, fForceVerification As Byte, ByRef pfWasVerified As Byte) As Boolean
End Function
End Class
Оттуда создайте базовый класс, от которого ваши унаследованные сборки могут наследовать:
Imports System.Reflection
Imports System.Security.Cryptography
Public Class SignedClassBase
Shared Sub New()
VerifyAssemblySignature(Assembly.GetCallingAssembly())
End Sub
Public Sub New()
VerifyAssemblySignature(Assembly.GetCallingAssembly())
End Sub
Private Shared Sub VerifyAssemblySignature(assembly As Assembly)
Dim wasVerified As Boolean
If Not (NativeMethods.StrongNameSignatureVerificationEx(assembly.Location, True, wasVerified) AndAlso wasVerified) Then
Throw New CryptographicException("Verification failed: Assembly signature did not match.")
End If
End Sub
End Class
А затем вызовите базовый конструктор из вашего производного класса:
Public Class Utils
Inherits SignedClassBase
Shared Sub New()
RuntimeHelpers.RunClassConstructor(GetType(SignedClassBase).TypeHandle)
End Sub
Public Sub New()
MyBase.New()
End Sub
End Class
Теперь, если создается измененная сборка, CryptographicException выбросит конструктор базового класса, предотвращая использование производного класса.
Таким образом, хотя сам по себе подписание кода напрямую не связано с безопасностью, принудительное выполнение подписи сборки может определенно повысить безопасность, которую вы уже установили, в сочетании с сильным запутыванием, где это необходимо. В этом отношении закрытый ключ ДОЛЖЕН оставаться секретным. Совместное использование закрытого ключа в проекте с открытым исходным кодом - это просто способ облегчить жизнь вовлеченным разработчикам. Гораздо лучше вместо этого подписать сборки как часть официального процесса сборки и сохранить свой секретный ключ в полном секрете. В противном случае любой может перекомпилировать сборку с потенциально вредоносным кодом, подписать ее своим закрытым ключом и распространить испорченные копии вашего проекта.