“My installation package includes one application and many libraries. I need to prevent hackers from replacing individual libraries, especially the license.dll. Using checksums might be an option, but I would have to recompile and distribute the entire package again.” This would be a typical problem faced by software developers everywhere. Their answer to this challenge, or to similar problems like a secure check of serial numbers, would normally be mini-certificates: a powerful tool for many use cases. What can they do?
A checksum is the end result of a function that turns data strings of any length into a single number. If the data is changed, the checksum changes as well. Popular examples include CRC and Modulo operations, which are frequently used to prevent or reduce mistakes in data entry or transmission. Credit card or IBAN numbers come with checksums to allow the systems to notice incorrect entries before the data is ever sent to the bank, retailer, or service provider.
Simple checksums are not viable defenses against malicious acts. For effective fraud prevention, cryptographic checksums are needed that change substantially in response to even a tiny change to the underlying data. It would be impossible to manipulate the data in such a way that the checksum itself remains unchanged, e.g. by adding blank spaces until the data corresponds to the same checksum again. One popular current choice for cryptographic checksums is SHA256; the MD5 approach that was used frequently in the past is now considered insecure.
Cryptographic checksums are not without their own limits: To test a checksum, one needs the same information from when it was created originally, i.e. the function itself and an optional salt value as the shared secret. This information needs to be kept in the software whose checksums are tested. If even a single attacker manages to get at this data, the entire system is compromised, as valid checksums could be created that could never be identified apart from the originals.
This conceptual restriction has led to some labyrinthine constructs, with checksums for different libraries kept in other libraries again or in the core application – unwittingly creating the problem of updating entire software packages mentioned already.
The solution can come from asymmetric cryptography, in the form of key pairs with one private key that is kept secret and one public key that is out in the open. The private key can be used only by their legitimate owner to sign something; the public key can then be used by anybody to check the signature. Having the public key does not, however, enable anyone to create a valid signature.
Asymmetric cryptography is typically a slow and laborious process that requires data of a certain size, which is why it is often combined with cryptographic checksums. First, a checksum of the data is created and signed with the private key. For later testing, the same checksum is created again and tested against the public key and signature. ECDSA and RSA are established processes in this area.
The Basic Tools
The basic toolkit for signing our libraries and applications is described here. As the first step in the development process, the public key is included in the software.
After compiling, the private key is used to create a signature for each module (library or application). The signature is delivered alongside the modules, either in a separate file or in a dedicated place in the resource section.
During testing, the checksum is created again, skipping the signature potentially contained in the resources. The resulting checksum is then checked against the signature and the public key.
One Signature Might Not Be Enough
This could be the end of the story, but the future might bring new challenges that need to be anticipated. Breaking with the clean code principle that calls on developers to not try and solve problems that do not exist yet, security developers should always think two steps ahead. One could ask:
Do we want to be protected if the private key is stolen?
Do we want to give multiple developers the ability to sign modules?
Should modules from business partners be allowed in our product universe?
Should test and operational systems be kept completely separate?
These are cases virtually perfect for mini-certificates. A mini-certificate essentially contains one public key, defined sets of rights (flags), and a signature for the public key. They are modeled on the example of the X.509 certificate, but much leaner and easier to use with a binary format defined by you.
How to Get a Mini-Certificate
In the first step, you create a new key pair, the so-called “root” keys. The public key is again integrated in the software. At the same time, another private key pair is made, and the private root keys are used to create a mini-certificate for the public key of the new pair. The private root key is then locked away, impenetrable and protected from illicit access. Experts recommend a hardcopy and two digital copies kept at two separate places. This is indeed a viable option, because the private root key is rarely needed again after this point.
You then use the new private key to routinely sign the modules you produce. The mini-certificate of the new public key is added to the modules, and the checks compare the certificate with the public root key and the signature of the protected data with the public key on the mini-certificate.
More Links, Stronger Chains – Chains of Certificates
This approach includes two tiers: the root key pair and the key pair for active use, which would form the recommended minimum set. The system could just as easily include more than two tiers, with the second private key signing the public key of a third key pair, eventually growing into entire cryptographic trees. Depending on the flags you have set, rights can be inherited, e.g. by assigning more mini-certificates.
You only need the private root key again, if additional keys are to be created or old keys removed. If the process uses more than two tiers, this is even less likely, because the keys of the second tier can be used for the same purpose. In that case, the root key would only ever be used again if second-tier keys are added or removed.
There are two strategies for removing keys:
A revocation list
Automatic expiration of certificates
A revocation list would record all void certificates. Devices that cannot access the list (e.g. because they are offline) would still work with the old, void certificates. To prevent this, automatic expiration would enforce certificate renewals. The quintessence would be the required transfer of data to the devices you want to cover. The choice between the two possible strategies should be a choice between “Reliability First” or “Security First”.
Secure Serial Number Checks
Mini-certificates are also a good choice for checking serial numbers securely: A CmDongle is given a key pair, with the private root key used to create a mini-certificate for the public key. This is then delivered to the user, e.g. as extended protected data on the CmDongle.
The testing system creates a so-called challenge that the CmDongle signs with the private key (or more specifically, both sides each create a part of the challenge). A response for the challenge and the mini-certificate are sent back and checked with the public root key to test the mini-certificate and make sure with the contained key that the response matches the challenge. If all goes well, the identity of the CmDongle is considered proven.
This process is already frequently used to check identities e.g. secure identities for Flexnet or secure authentication of laser machines in service networks.
Use Cases for Integrity Protections
Beyond acting as a secure proof of ID, the technology is primarily used to safeguard modules from being replaced or otherwise modified. A license.dll could not be replaced with a fake .dll that tricks the device into thinking that a license is available. The system is an elegant and easy-to-use means of encapsulating licenses, but Wibu-Systems still recommends automatically protecting each module with CodeMeter Protection Suite and integrating license checks there. How CodeMeter Protection Suite can bolster the protection for software is outlined in “Automatic Protection for your Software”.