我是 .net 的新手,想知道如何防止他人使用/引用我的编译库。我做了一些研究,但没有找到明确的答案。是 Authenticode 还是强名称,还是其他什么?它们的可靠性如何?
这些库是商业桌面软件的一部分。
我是 .net 的新手,想知道如何防止他人使用/引用我的编译库。我做了一些研究,但没有找到明确的答案。是 Authenticode 还是强名称,还是其他什么?它们的可靠性如何?
这些库是商业桌面软件的一部分。
如何防止他人使用我的编译库?
我想知道如何防止别人使用我的牙刷。我找到了一个解决方案。我不让他们接触我的牙刷。
如果你不想让别人使用你的软件,那么不要给他们你的软件。
如果你希望有人能够使用你代码的功能而不知道实现细节,那么可以编写一个Web服务,将软件放在Web服务器后面,人们可以通过你提供的服务使用你的软件。他们只会看到Web服务器,而看不见你的实现细节。
是Authenticode还是strong names或其他东西?
不是。你的场景是你希望保护自己这个软件提供者,免受用户的侵害。这完全是相反的。 .NET安全系统的设计目的是保护用户免受不良软件提供者的伤害。
Authenticode和strong names都是一种系统,使软件的用户可以获得证据,证明该软件确实是由他们认为的提供者所提供,而不是由假冒你身份的恶意黑客提供的。
例如,假设我变成了一个邪恶的人,向你发送一个名为“System.DLL”的软件升级版,声称来自微软,但实际上会监视你输入的密码并将其发送给我。我可以发送一个名为“System.DLL”的DLL文件,但我不能发送一个带有Microsoft strong name的DLL文件,因为我不能制造Microsoft strong name。只有Microsoft才能这样做,因为Microsoft的签名密钥嵌入在11号楼的深处,并由激光鲨鱼之类的东西守卫着。Strong names保护你免受我伤害;它们不保护Microsoft。
同样,强名称可以保护您的客户不受冒充您身份的攻击者的侵害。它们并不能保护您免受客户的攻击,因为他们才是受到攻击的人!商业桌面软件模型假定客户信任软件提供商按照其许可证使用该软件。如果您不相信您的客户,那么您需要一个完全不同的模型,例如将软件保存在您的Web服务器上,并仅通过Web接口允许访问。这些库是商业桌面软件的一部分
'Note this class in C# will (and MUST) be Sealed, which is the equivalent in VB of NotInheritable with Shared Members
Public NotInheritable Class ProtectMyDLL
Private Shared ReadOnly MyPublicKey As String = "<RSAKeyValue><Modulus>SomeLongBase64StringHere</Modulus><Exponent>SomeShortBase64StringHere</Exponent></RSAKeyValue>"
Private Shared _DataToSign(32) As Byte 'Recommended size in Bytes, for SHA256 hash signature (256 bits = 32 bytes)
Public Shared Property SignedData As Byte() 'The caller will be asked to put the signed version of DataToSign here
Public Shared ReadOnly Property DataToSign As Byte()
Get
If _DataToSign Is Nothing Then 'If empty then generate a new random string (string size is determined by the size of the Byte() array: 32)
Using MyRndGen = System.Security.Cryptography.RandomNumberGenerator.Create
MyRndGen.GetBytes(_DataToSign)
End Using
End If
Return _DataToSign
End Get
End Property
Public Shared Function UserIsGenuine() As Boolean
Using MyRSA As New System.Security.Cryptography.RSACryptoServiceProvider
MyRSA.FromXmlString(MyPublicKey)
UserIsGenuine = MyRSA.VerifyData(DataToSign,
System.Security.Cryptography.CryptoConfig.MapNameToOID("SHA256"),
SignedData)
_DataToSign = Nothing 'This forces the data to be signed to change each time an access to the DLL is granted; otherwise the data to be signed will change only each time the Application is started. Argueably necessary, argueably consumming unnecessary resources..
End Using
End Function
End Class
Public Class MySecretClass
Public Shared Sub IntelectualPropertyMethod()
If Not ProtectMyDLL.UserIsGenuine() Then
Throw New System.AccessViolationException("Caller signature could not be verified.")
Exit Sub
End If
'... This code is protected
End Sub
End Class
Public Class CallerFromOutsideTheProtectedDLL
Public Sub Main()
ProtectMyDLL.SignedData = SignData(ProtectMyDLL.DataToSign) 'Must do this before every calls of a protected method, unless the _DataToSign = Nothing line is removed, in which case you onlyned to add this line once (see Secret DLL file).
Call MySecretClass.IntelectualPropertyMethod()
End Sub
Private Function SignData(MyData As Byte()) As Byte()
Return MyCrypto.SignWithMyPrivateKey(MyData) 'If you want to avoid having to provide a Private Key in an assembly, you can pass MyData through a WebAPI where the Private Key would be 100% securely kept secret. But then your App needs an access to the web, at least from times to times.
End Function
End Class