-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Method to generate LicenseKey signature string is fragile #66
Comments
@Paramethod thank you for the feedback. You are right about that the order is not guaranteed, and MSDN advises against relying on a particular order.
On the server side, we use the declared order. From my experience, all versions of .NET Framework (from 3.5) use the declared order. This problem has only occurred for users running on Mono, for which a different protocol is used: https://help.cryptolens.io/getting-started/unity If possible, I would recommend to use a different overload of Key.Activate which does not take ActivateModel. The protocol that is used is the same that we use in other languages and is the one that should preferably be used in newer implementations. // call to activate
var result = Key.Activate(token: auth, productId: 3349, key: "GEBNC-WZZJD-VJIHG-GCMVD", machineCode: "foo");
// obtaining the license key (and verifying the signature automatically).
var license = LicenseKey.FromResponse("RSAPubKey", result); Your suggestion sounds good. I think it should be enough to have the order enforced using attributes and keep the normal dictionary, but I need to review the docs more carefully. A possible solution could be to change the return source.GetType().GetProperties(bindingAttr).Where(x=> x.MemberType == MemberTypes.Property).OrderBy(x=> x.GetCustomAttributes(typeof(OrderAttribute), false).FirstOrDefault()).ToDictionary
(
propInfo => propInfo.Name,
propInfo => propInfo.GetValue(source, null).ToStringCultureSpecific()
); I did some tests this morning but got a few errors, so I will look at it a bit later. P.S. The long term plan is to completely abandon the old protocol and move to the new one in the .NET SDK. [1] https://docs.microsoft.com/en-us/dotnet/api/system.type.getproperties?view=net-5.0 |
Hi @artemlos Since this is considered old protocol I think the simplest solution to make the older protocol stable is add this method to the
I will try the new protocol today. As for reflection and the |
When verifying if a key is genuine, the signature string is a csv string created from a property name/value dictionary generated using reflection on the license key instance.
cryptolens-dotnet/Cryptolens.Licensing/SKMv3/ExtensionMethods.cs
Line 185 in 4da0f4c
Since the order of the elements is critical in the signature csv string, this is extremely fragile.
SortedDictionary
orOrderedDictionary
could be used, but I don't think it is enough in itself.LicenseKey
class it would break.I see two possible solutions:
Create a dedicated
string LicenseKey.ToCsvString
method that would return precisely the csv string. Order and which property is included is totally controlled.An
OrderedDictionary
used in combination of eitherIndexAttribute
orJsonPropertyAttribute(Order = xx)
on each property with the exact order. When using reflection we sort the items per their assigned index. Properties that are not decorated are ignored.I think solution 1 is the easiest, but explicitly tagging each serialized properties with
JsonProperty(name, index)
would make it more robust and obfuscation friendly because serialization would not rely on member names, but literal strings with the serialized property name. Perhaps a combination of 1 and 2. Thoughts? Ideas?How is the order of the properties determined server-side when generating the signature?
The text was updated successfully, but these errors were encountered: