In this episode, we will show you everything about Code Signing: how to get a certificate (commercial certificate or your own one), how to sign a code, verify those signatures and show how do they work and what we can do about it. We will also discuss what will happen with your signed code if your certificate expires.
I have my virtual machine up and running and on my desktop, I have my RDcache utility. This utility is written for some forensic purposes and it’s not digitally signed. It was written a long time ago. You can see there is no digital signature over here. There is an interesting fact here: it is not written as you can spot by the icon in any of Microsoft development environments and still can be perfectly well signed, without any problem.
Step by step on how to get the certificate
To have a digital signature, first, we have to have the certificate used for signing.
It can be any certificate with the proper purpose, for example, I can run PowerShell and then issue a command New-SelfSignedCertificate with the proper KeyUsage and then CertSign and so on and so on. But such certificate will be next to useless because it will be only trusted by myself. It will verify if the file was not altered. It’s not the best approach.
If you are signing file for internal usage like your own company utilities and so on, you can use CA your own Certificate Authority for this purpose. To do this you have to manage templates. I will switch to Certificate Authority over here. I will launch my Certificate Authority console and under certificate templates and by default there is no template about code signing. It will load in a second. It has to be loaded from Active Directory. Now I can right click, select manage, go to the templates and select code signing template, duplicate it and apply my own name: CQ Signing.
And go to other properties to verify how I can issue a certificate based on this template if all those properties are acceptable for me. Of course, I can click okay and I have a CQ Signing template being present.
If I return to the Certificate Authority console I can click new certificate template to issue and I can select secure signing for code signing purposes. Click okay and now my Certificate Authority will issue certificates for the purpose of signing.
If I return right now to my machine with that executable for being signed I can exit from PowerShell, and go to certificate management by typing certmgr. It will allow me to ask for the certificate.
You can see there is no certificate within the personal store and I can:
- click all task,
- request a new certificate,
- and using this wizard, refer to my Active Directory,
- wait for the information about the certificate templates
You can see CQ Signing is present over here, I can click and click enroll and after enrollment, which should be successful, in a couple of seconds, you will see the certificate will appear on the list.
Using the certificate for signing
It means I have the code signing certificate on my user account and now I can use this certificate for the signing. The status is succeeded. If I click finish, under certificates, I can see a certificate issued to the administrator because I’m logged on as an administrator with intended purpose code signing and is issued by my lab CA right now.
So how can I use this particular certificate for signing a binary file?
I can use any of commercial tools but we are living with PowerShell so it can be done in a smarter way. Let’s launch PowerShell again. Remember that PowerShell can access certificates like the files on the drive so I can do Get-ChildItem and do cert:\ and now select CurrentUser, My and then I can select the certificate. This is the certificate I have on my machine. I can observe it, you can see it’s freshly issued. I can access its properties and what I can do is to assign this certificate (by using Get-ChildItem( into a PowerShell variable.
So I will do $cert1 equals Get-ChildItem and after the certificate I have it stored in the $cert1 variable.
What I have to do right now is to use a commandlet Set-AuthenticodeSignature, and then specify parameters.
The first one is about the certificate, and I can specify my variable, $cert1. The next parameter is about file path, and now I can specify on my desktop there is an RDcache.exe. That’s actually all. You can see the status is valid. If I right click on the RDcache and go to properties, you can see a couple of tabs more than previously, especially the digital signature. So you can have the name of the signer taken out of the certificate, you can see the digest algorithm which is not the most modern one, I can say, and should be not used.
We can specify the algorithm as a parameter for PowerShell commands. If I click on details I will see details of the certificate from the Certificate Authority. This way of signing is working in an acceptable way, especially if you can view the certificate, you can see this is the certificate that is trusted, for example within my environment. Which is okay for many internal usage applications.
But it’s not the best approach for a publicly available code. Another thing is that this way of signing your stuff is about no timestamp over here. Because here we do not have any timestamp. If I click onto details again, you can see under the properties of the certificate the validity period is for one year. What does it mean? It means if the certificate is not valid (his validity expired) if this time finishes this signature will be no longer valid because the certificate is no longer valid.
Validity date of the certificate
It is pretty interesting because we can imagine, for example, drivers for our devices being present in the operating system and that time of the validity of the certificate is over. It means those drivers will not work. Of course, this is not a scenario you can observe in your operating system. If you verify the validity date of the certificate for your drivers you can easily realize some of your drivers have already their certificate after the expiration date. Because the certificate was valid at the moment of signing, not the moment of running or verifying the signature. So for having proof that the certificate was valid at the moment of signing, the only way of doing this, is to use a special time stamping. Providing trusted source of the time for the signing of the certificate.
Use time stamping
For such purpose, I will switch to my command line here. And here, I have:
- my RDcache which is not digitally signed yet,
- my PFX file which is official CQURE code signing certificate.
I can try to use it for signing with the time stamping being present. I will:
- Launch PowerShell.
- Do $cert2 (Let’s name it a different way, even if it’s another machine). Get-PfxCertificate, because I will take the certificate not from my store but out of the PFX file.
- The file is SignCqureAG.PFX. If I do not specify any password here, I will be prompted for the password.
- In the $cert2 I have my certificate being stored with all the properties such as subject and so on.
- I can use exactly the same command Set-AuthenticodeSignature, and I can specify that Certificate is $cert2 and the FilePath is RDcache.exe.
- The third parameter, need it now, TimestampServer is for my case http://tsa.startssl.com/timestamp
Right now I, am obtaining a stamp for the time, using the certificate. If I go into properties of this file I can use explorer for this purpose. I can easily see, under properties, I have digital signatures and you can see timestamp is being applied.
My certificate will expire in two years but it will not have to be valid to have a file being digitally signed in an acceptable and trusted way.
Actually, there’s a huge bunch of files you can digitally sign, but it’s most interesting about your MSI files, about .exe files, and about .dll files because those are spread most widely.
As you can see it is not a rocket science if you have a certificate you can digitally sign your stuff, and make it trusted by others not only by you. You can easily verify if some content was manipulated or not.
Is it useful for IT Pros and Developers?
The question may appear if it is useful for typical IT Pros, or maybe more for developers. Actually, I tried to explain it in a way being useful for IT pros because IT pros are the main set of our viewers, our readers. To have IT pros spreading this information to developers.
Please go to your developers right now, and ask them about the code they are compiling, and executable files they are developing and try to establish a signing process and start signing your software right now.
My advice is to try to play with these features on your own. It’s very simple as you can see. It’s very useful. There’s nothing harmful in signing your own code. Please try and see how it’s working in live environments as well. You can also ask some questions because sometimes this topic is not very straight forward.
Have some questions about Code Signing?
I will try to help you if you have any practical issues with applying such things – just put some comments in the comment section.
*author Grzegorz Tworek