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.
|
var rawResult = licenseKey.AsDictionary(); |
Since the order of the elements is critical in the signature csv string, this is extremely fragile.
- The order of the elements in a dictionary is non-deterministic. Most of the time they will enumerate in the order elements were added, but it is not guaranteed. Perhaps a
SortedDictionary or OrderedDictionary could be used, but I don't think it is enough in itself.
- The properties values are discovered and added using reflection. This is not problem, but the order of the members in the class definition will affect the outcome. So any code reorganization would break the output. Additionally if properties unrelated to the serialization/deserialization are added to a derived
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 either IndexAttribute or JsonPropertyAttribute(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?
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.
SortedDictionaryorOrderedDictionarycould be used, but I don't think it is enough in itself.LicenseKeyclass it would break.I see two possible solutions:
Create a dedicated
string LicenseKey.ToCsvStringmethod that would return precisely the csv string. Order and which property is included is totally controlled.An
OrderedDictionaryused in combination of eitherIndexAttributeorJsonPropertyAttribute(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?