HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

.NET 4.5 licensing subsystem using RSA-4096 strong name key, SHA256 signed XML, and assembly signature enforcing

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
enforcingsubsystemkeyrsasignatureandxmlassemblynetlicensing

Problem

Abstract

For the past week I have been looking at taking advantage of the .NET 4.5 improvements to code signing and XML signing to produce a licensing subsystem I can use to license my own products. I now have the thing working pretty well, and I am looking for input as to how it could be improved, or what security issues I might have missed. Please feel free to propose enhancements and point out flaws if you see them.

What I wanted was to be able to take a solution with assemblies signed with a strong name key, and use that same key pair to sign licenses on my server and validate them in the client application. Historically the strong name assembly signature in .NET was always pretty weak. Until .NET 4.5 it only supported RSA keylengths of 1024 bits and used the now obsolete SHA1 hashing algorithm to produce signatures. The assembly signature is also not enforced by default, and only used to identify assemblies in the GAC. NET 4.5 has now added the support for any key length, and for the SHA256 signatures. The same support was also added to the SignedXml class. I wanted to use the strong name key pair to A) avoid having to distribute a separate public key and B) avoid having to dish out for a suitable CA certificate. I had an idea to use reflection to extract the public key from the signed assembly and use it to first validate the assembly integrity by enforcing signature validation, and then validate the license when an assertion was made.

What I am looking for here is constructive criticism, possible vulnerabilities in the approach (other than the private key becoming known), or how I could make this better/more secure.

The Code

First, I created a strong name key file with a 4096-bits RSA key:

```
Public Shared Function SaveKeyPairToSnk(rsa As RSACryptoServiceProvider, filename As String) As Boolean
Try
Using fs As New FileStream(filename, FileMode.Create, FileAccess.Write)
Dim bytes = rsa.ExportCspBlob(True)
fs.Write(byt

Solution

I Think you solution is a good compromise between efford and security.

However, verifing the signature of the assembly from inside the assembly is not a big approvment of security. If anybody is able to tamper your assembly, she can just remove the check. One further improvment could be to move the verification to a native asembly. To ensure that the method of the native assembly is called, you could encrypt one or more of the application's base assemblies and load (and decrypt) them with the method of the native assembly that verify the entry assembly.

Another improvment could be the way you handle the hardware ID.
You generate a single harware ID from 3 device ids (CPU, HD and Motherboard). If one of the device ids change, your hardware ID does not match anymore. A more tolerant solution is to check that at least 2 of the 3 device ids matches. That ensures that your license is still valid if the customer change its processor for instance.

Context

StackExchange Code Review Q#127854, answer score: 2

Revisions (0)

No revisions yet.