Reputation: 109
I'm new to .net and would like to know how I can prevent others from using/referencing my compiled libraries. I did some research but didn't find a clear answer. Is it authenticode or strong names or something else? and how reliable is it?
the libraries are part of a commercial desktop software
Upvotes: 5
Views: 3184
Reputation: 1565
Assuming no one will decompile your assembly (if this happens, it is just over anyways): The best way to protect your Secret DLL is by having your functions requiring some data to be signed.
In each of the Methods you whish to protect you could:
MySignedData
.Function UserIsGenuine(MySignedData as String) as Boolean
(sorry, VB.NET here..) just before your code.Further considerations: The data to sign should change each time, otherwise the Evil User would just need to catch an instance of MySignedData and keep re-sending it. So you need to force the DataToSign
to be different each time.
DataToSign = Hash(System.Time + Salt)
. But you are depending on the system time, which may be altered.DataToSign = RandomHashGeneratedBySecretDLL()
located inside the Secret DLL.(in VB.NET, sorry again)
'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
Upvotes: 0
Reputation: 1827
I think I get what you're saying: you've put a lot of effort into a library that is essential to your application, and you don't want someone else to use a copy of that dll in their own application basically stealing your code, even if they can't see it. The framework is not built for this. You can hide certain code using access modifiers, but public is still public. However...
What I used to do when putting a component in a library that I know could be copied and used by someone else is to give specific classes a property that must be set to my name © and year. Without that exact text, the class won't work (or will work, but poorly). Since they can't change the code, they'll be forced to admit they stole it. You could even go as far as to put a password in there. This solution isn't perfect, of course, but it's the simplest. I don't do it any more though, because I just don't care.
EDIT: come to think of it, there are some commercial components that require a login before they can be used. Usually in the form of a username and a byte array that you buy from the author.
Upvotes: 1
Reputation: 659956
How I can prevent others from using my compiled libraries?
I would like to know how I can prevent someone from using my toothbrush. I have found a solution. I don't give them access to my toothbrush.
If you don't want people to use your software then do not give them your software.
If you want someone to be able to use the functionality of your code without knowing the implementation details then write a web service, put the software behind a web server, and people can use your software via the service you've provided. They only see the web server, not your implementation details.
Is it authenticode or strong names or something else?
No. Your scenario is that you wish to protect yourself, a software provider, from your users. That is exactly backwards. The .NET security system was designed to protect your users from bad software providers.
Both authenticode and strong names are systems whereby a user of software can obtain evidence that the software really was provided by the person they believe it to be provided by, rather than by evil hackers pretending to be you.
For example, suppose I become evil and send you a new version of System.DLL that I say is a software upgrade from Microsoft, but actually watches you type in passwords and emails them to me. I can send you a DLL called "System.DLL", but I can't send you one that has the Microsoft strong name because I can't make a Microsoft strong name. Only Microsoft can do that, because the Microsoft signing key is buried deep within Building 11 and guarded by sharks with laser beams or something. Strong names protect you from me; they don't protect Microsoft.
Similarly, strong names protect your customers from attackers pretending to be you. They don't protect you from your customers. You are not the one who is under attack; they are!
the libraries are part of a commercial desktop software
The commercial desktop software model presupposes that customers are trusted by software providers to use the software in accordance with their license. If you don't trust your customers then you need an entirely different model, like keeping the software on your web server and only allowing access via a web interface.
Upvotes: 40