FireMonkey apps for iOS and Android are automatically signed during the deployment process in Delphi – this is especially important for iOS apps and was therefore implemented in the Delphi IDE.
For Windows applications (no matter if 32 or 64 bit) there is no signature option in Delphi. This might lead to many Delphi apps being distributed unsigned. However, this is no longer recommended for Windows 10 or later, because the “SmartScreen-Filter” introduced with Windows 10 blocks “untrusted” applications by default. An unsigned application (EXE) is per se “untrustworthy”, because its origin cannot be verified.
Every now and then you will find the not very clever “tip” on how to turn off this SmartScreen check. The only correct approach is to only release signed applications as a developer (no matter if public or in-house)! As a user you should step on the toes of suppliers who continue to sell unsigned applications.
In order to sign an EXE, a valid certificate that supports code signing is required. Such certificates are issued by providers like Comodo, Thawte, Symantec and others. Depending on the chosen price range, the providers carry out a more or less intensive identity check of the applicant – after all, the certificate should be able to clearly identify the company or person who delivers an application. The annual costs are in the lower to middle three-digit range.
I could not find any usable free certificates (e.g. LetsEncrypt avoids the effort of an identity check), the cheapest way is to order a Comodo certificate via CodeSignCert. There you are included with $75 for one year.
I recently ordered a new certificate. On the above-mentioned page of CodeSignCert I chose the “SECTIGO CODE SIGNING” variant for $75/year. This worked fine.
Signing in Delphi
First, you have to install the corresponding Windows 10 SDK which contains the so-called “signtool.exe” from Microsoft. The 32-bit version will then typically be found in a path similar to this : C:\Program Files\Windows Kits\10\bin\x86\signtool.exe
Now you have to consider how to handle the certificate. There are two possibilities:
- Installation in the Windows certificate store and thus the use of the Windows own protection mechanism.
- Save the certificate as a PFX file and store the password in the application build process.
Finally, it must be remembered that this certificate is to be understood as an identity card. So you should not just leave it “lying around somewhere”, because otherwise, everybody could use this identity for his own purposes. Especially checking into a source control system does not seem to make much sense here.
<I usually use the Windows certificate store, where I have a central overview of my certificates and can quickly see when a certificate expires.
Basically, you can now sign a compiled Delphi application by hand by entering the following command on the command line:
"C:\Program Files\Windows Kits\10\bin\x86\signtool.exe" sign /n "developer experts" /tr http://timestamp.comodoca.com /du https://www.developer-experts.net C:\Projects\SignTest\Win32\Release\SignTest.exe
The other options:
/tr – a so-called timestamp server is specified here. Different certificate suppliers (the so-called CAs) operate these, I use the server of Comodo here – but it does not necessarily have to be the server of the own certificate supplier. With this option (in short) a hash of my exe is transmitted to the timestamp server, the server then issues a signature to this hash, which is provided with a timestamp generated on the server. This is then added to the actual signature. The procedure is to prevent that the supplier of an EXE can’t “cheat”, i.e. can’t date forward or backward.
Attention: Several older blog entries on this topic only use the /t option – but this leads – without further specification of an algorithm – to the use of the outdated SHA1 procedure. The option /tr, on the other hand, works according to RFC 3161 and negotiates at least SHA256 with the server.
/du – adds the given URL as “extended description” to the signature. This is particularly suitable for a manufacturer URL
In order not to have to execute this signing process manually every time, you can include this in the post-build option of the respective Delphi project. I use the release configuration for this because only this one goes to the customer.
Note that you can specify “($OUTPUTPATH)” as the signature target so that the path is not hardcoded – and you can copy and paste it into other projects 😉
Additionally, the pre-build event “del ($OUTPUTPATH)” is important because otherwise, the signing might fail.
At least on 64-bit Windows 10 versions the default path of the SignTool seems to have changed in the meantime so that the whole command now looks like this:
"C:\Program Files (x86)\Windows Kits\10\App Certification Kit\signtool.exe" sign /n "CERTIFICATE NAME (CN or Subject)" /tr http://timestamp.comodoca.com /du https://www.developer-experts.net "$(OUTPUTPATH)"
With each “build” the EXE is now signed in the release configuration – the debug configuration remains unchanged. Especially with very large projects, a debug EXE can quickly become several hundred MB in size, which takes some time to sign.