12,065,888 members (32,897 online)
As it often happens with security related issues, you are forced to look for a needle in the haystack to find a seemingly obvious solution. Signing and checking the code's signature is no exception. Most open source, freeware and shareware developers do not provide signed applications (for different reasons), and that is why we see so often Windows warnings about not signed code:
This article contains only basic information concerning issues of signing and verifying signature of Windows applications.
Many of us probably didn't even know that "Signing a deployment was made optional in the .NET Framework 3.5 SP1." (MSDN)
Especially, taking into account MSDN's own words from Introduction to Code Signing:
One of the larger questions facing the software industry is this: How can users trust code that is published on the Internet? Currently, most Web pages contain only static information, but soon they will be filled with controls and applications that are downloaded and run locally, on the user's computer. Packaged software uses branding and trusted sales outlets to assure users of its integrity, but these are not available when code is transmitted on the Internet. Additionally, there is no guarantee that the code hasn't been altered while being downloaded. Browsers typically exhibit a warning message explaining the possible dangers of downloading data, but do nothing to actually see whether the code is what it claims to be. A more active approach must be taken to make the Internet a reliable medium for distributing software.
Signing code is still not popular. Mostly because you have to pay money to obtain a certificate, and it adds new (optional) procedure to deployment process. But some developers start to ask (Stackoverflow.com):
We produce a content management system. It's a DB-based system, used only by businesses and organizations, and never downloadable from the Internet, i.e., it's not the kind of software someone might stumble upon and wonder what it is and whether it's safe to run. Over the 20+ years our system is being sold, its executables have never been digitally signed. I'm wondering if it is time for us to start signing them.
So, for anyone interested in the problem, this article can provide the necessary basic information about code signing steps. Every data security related process is so complex that to avoid (or to reduce to minimum) possibility of misunderstanding or ambiguous definitions, I will often quote MSDN and sometimes other sources.
To sign your deployment, you must have a code-signing certificate. You can either create your own test certificate or obtain a certificate from a root certificate authority (CA)—typically, vendor or your server support team. When you have a certificate from a CA, it displays the publisher in the installation dialogs, which makes your application appear more trustworthy. (MSDN)
A digital certificate is a file that contains a cryptographic public/private key pair, along with metadata describing the publisher to whom the certificate was issued and the agency that issued the certificate. (MSDN)
A certificate is issued to an entity by a third party that is trusted by both of the other parties. So, each recipient of a signed message decides if the issuer of the signer's certificate is trustworthy. …CryptoAPI has implemented a methodology to allow application developers to create applications that automatically verify certificates against a predefined list of trusted certificates or roots. This list of trusted entities (called subjects) is called a certificate trust list (CTL). (MSDN)
The third-party trusted authority is usually a well-known company, such as Verisign. (See Wikipedia)
Verisign Code Signing certificate can cost for organization from 300 to 500 USD/year. (See examples in Web stores)
Microsoft has developed a certificate store technology to reduce complexity. Using this technology, when a user enrolls to obtain a certificate, they specify the private key information, the CSP (cryptographic service provider) information, and the certificate store name for the certificate. The certificate will then be stored in the certificate store and be associated with the other items. When the user wants to sign a document, they only need to identify the certificate in the certificate store. The code signing tool will retrieve the certificate, the private key, and the certificate chain for the CSP, all based on the specified certificate. (MSDN)
Certificate store - Typically, a permanent storage where certificates, certificate revocation lists (CRLs), and certificate trust lists (CTLs) are stored. It is possible, however, to create and open a certificate store solely in memory when working with certificates that do not need to be put in permanent storage. The certificate store is central to much of the certificate functionality in CryptoAPI. (MSDN)
Certificate stores are located on every Windows machine, i.e., there is no need to go on the Internet to verify the certificate in question. Windows ... stores a certificate locally on the computer or device that requested it or, in the case of a user, on the computer or device that the user used to request it. The storage location is called the certificate store. A certificate store will often have numerous certificates, possibly issued from a number of a different certification authorities. (MSDN)
Signature is verified during deployment of application and when the application is run for the first time on the customer's machine. The verification procedure is generally the same - Signature verification component checks the integrity of the file. It verifies the signature before deploying the file, by using a public key in a certificate.The certificate is stored in the OS certificate store. (See MSDN)
There are two signing technologies on Windows: Authenticode and Strong Name signing. Note that Microsoft does not recommend to use Strong Name Signing as a replacement for Authenticode.
Authenticode allows vendors of downloadable executable code (plug-ins or ActiveX controls, for example) to attach digital certificates to their products to assure end users that the code is from the original developer and has not been altered. Authenticode lets end users decide for themselves whether to accept or reject software components posted on the Internet before downloading begins. (MSDN Security Glossary)
If you use a test (self-created) certificate, the installation dialogs will display an "Unknown publisher" message. For applications deployed internally in an organization, this is an acceptable practice. (MSDN)
The procedure of creating your own test certificate is described in the MSDN article, How to: Create Your Own Test Certificate. In the end, you will have to sign the application using Microsoft's utility SignTool.exe.
C:\signtool sign /f notifysftest.pfx /p research test.exe Done Adding Additional Store Successfully signed: test.exe
Important: When signing the code with certificate issued by CA (such as Verisign), it is important to add timestamp for certificate that will ensure that the application will continue to run after the validity period of the original certificate. (MSDN, Authenticode Signature (UAC)). For that, you have to be connected to the Internet because you apply for timestamp on the Certificate Authority's site.
Be aware that popular signature checking tool sigcheck from Sysinternals will print the "Invalid signature" in case you have signed the application with your own test certificate. This utility also allows you to check the signature of drivers and DLLs (that can't be shown in standard file's context window "Properties" tabs).
Strong-name signing, or strong-naming, gives a software component a globally unique identity that cannot be spoofed by someone else. Strong names are used to guarantee that component dependencies and configuration statements map to exactly the correct component and component version. Strong name consists of the assembly's identity (simple text name, version number, and culture information), plus a public key token and a digital signature. For Visual C# and Visual Basic projects, Visual Studio enables strong-naming through the Signing pane in the Project Designer. For Visual C++ projects, you use linker options to sign your assembly. (MSDN, Strong-Name Signing for Managed Applications)
Signing your deployment with Strong Name (using sn.exe tool) will be recognized as signature by sigcheck tool printing "Strong Name: Signed". But this option exists only for .NET managed applications (including C++/CLI).
Strong-naming gives an application or component a unique identity that other software can use to refer explicitly to it. For example, strong-naming enables application authors and administrators to specify a precise servicing version to be used for a shared component. This enables different applications to specify different versions without affecting other applications. In addition, you can use the strong name of a component as security evidence to establish a trust relationship between two components. (MSDN, Strong-Name Signing for Managed Applications)
You sign with Strong Name using sn.exe tool. Enable in VC++ 2010: Properties->Configuration Properties->General->Common Language Runtime Support-> Common Language Runtime Support /clr).
The following command creates a new, random key pair and stores it in keyPair.snk.
sn -k keyPair.snk
The following command stores the key in keyPair.snk in the container
MyContainer in the strong name CSP:
sn -i keyPair.snk MyContainer
Finally, add keyPair.snk in Properties->Configuration Properties->Linker->Advanced->Key file.
And add container name
MyContainer in Properties->Configuration Properties->Linker->Advanced->Key container.