防止他人使用我的dll

时间:2015-02-15 01:23:35

标签: c# .net

我是.net的新手,想知道如何防止他人使用/引用我编译的库。我做了一些研究,但没有找到明确的答案。它是authenticode或强名称还是其他什么?它有多可靠?

这些库是商业桌面软件的一部分

3 个答案:

答案 0 :(得分:38)

  

如何防止他人使用我编译的库?

我想知道如何防止有人使用我的牙刷。我找到了解决方案。我不让他们使用我的牙刷。

如果您不希望别人使用您的软件,那么不会向他们提供您的软件

如果您希望某人能够在不知道实施细节的情况下使用代码的功能,那么请编写Web服务,将软件放在Web服务器后面,人们可以通过以下方式使用您的软件您提供的服务。他们只看到Web服务器,而不是您的实现细节。

  

是authenticode还是强名称还是其他什么?

没有。您的方案是希望从您的用户保护您自己,一个软件提供商。这完全倒退了。 .NET安全系统旨在保护您的用户免受坏软件提供商的侵害。

软件用户和强名称都是系统,软件用户可以获得证据,证明该软件确实是由他们认为由其提供的人提供的,而不是伪装成你的邪恶黑客。

例如,假设我变得邪恶并向您发送一个新版本的System.DLL,我说这是一个来自Microsoft的软件升级,但实际上是在看着您输入密码并通过电子邮件发送给我。我可以发送一个名为“System.DLL”的DLL,但我不能发送一个具有Microsoft强名称的DLL,因为我不能使成为Microsoft强者名称。只有微软才能做到这一点,因为微软的签名密钥深藏在11号楼内,并由鲨鱼用激光束或其他东西守卫。强名称保护来自;他们不保护 Microsoft

同样,强名称可以保护您的客户免受攻击者伪装成您。它们不会保护 您的客户。你不是受到攻击的人;他们是!

  

这些库是商业桌面软件的一部分

商业桌面软件模型预先假定软件提供商信任客户以根据其许可使用该软件。如果您不信任您的客户,那么您需要一个完全不同的模型,例如将软件保留在您的Web服务器上,并且只允许通过Web界面进行访问。

答案 1 :(得分:1)

我想我得到了你所说的:你已经付出了很多努力进入一个对你的应用程序至关重要的库,你不希望别人在他们自己的应用程序中使用该dll的副本基本上窃取你的代码,即使他们看不到它。该框架不是为此而构建的。您可以使用访问修饰符隐藏某些代码,但公共仍然是公共的。然而...

将组件放入我知道可以被其他人复制和使用的库中时我常常做的是给特定的类一个必须设置为我的名字©和年份的属性。没有那个确切的文本,该课程将无法工作(或将工作,但很差)。由于他们不能改变代码,他们将被迫承认他们偷了它。你甚至可以在那里输入密码。当然,这个解决方案并不完美,但它是最简单的。我不再这样做了,因为我只是不在乎。

编辑:想到这一点,有一些商业组件需要登录才能使用。通常采用您从作者处购买的用户名和字节数组的形式。

答案 2 :(得分:-1)

假设没有人会反编译您的程序集(如果发生这种情况,反正就结束了): 保护您的Secret DLL的最好方法是使您的函数需要对某些数据进行签名。

您希望保护的每种方法都可以:

  1. 让他们附加一个名为MySignedData的参数。
  2. 在代码之前插入Function UserIsGenuine(MySignedData as String) as Boolean(对不起,这里是VB.NET。)。

其他注意事项:要签名的数据每次都应该更改,否则,邪恶用户只需要捕获MySignedData的实例并继续重新发送它即可。因此,您需要强制DataToSign每次都不同。

  1. 最简单的方法是使用DataToSign = Hash(System.Time + Salt)之类的方法。但是您取决于系统时间,该时间可能会更改。
  2. 更复杂的是将DataToSign = RandomHashGeneratedBySecretDLL()放在Secret DLL中。

下面的完整示例。

(在VB.NET中,再次抱歉)

受保护的DLL

'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