Creating a self signed Code Signing certificate is not easy to figure out, but is easy to do. The Microsoft SDK's includes a utility called makecert.exe. Since I develop applications for private use and use ClickOnce deployment, I needed a certificate to sign my application that would not expire in one year. I took it a step further and created my own Root Certificate which I then used to create and sign my Code Signing certificate.
To create a root certificate go to the Windows command prompt and type the following command. Makecert.exe should be in the local directory or located in the windows path.
This created a root self signed certificate that will expire in 2050. The certificate was stored in the local certificate store. We will export it to a file shortly.
makecert -r -pe -a sha1 -n "CN=MyCompanyNameRoot, Efirstname.lastname@example.org, C=US" -b 01/01/2012 -e 01/01/2050 -ss My
Next I created my Code Signing certificate. If you are working as a group on a project and want each developer to be able to sign assemblies with a unique certificate, just create one for each.
This created two code signing certificates and stored them in the local certificate store.
makecert -pe -a sha1 -n "CN=EmpOneCodeSigning, OU=www.example.com, C=US" -b 01/01/2012 -e 01/01/2050 -eku 18.104.22.168.22.214.171.124.3 -ss My -is My -in "MyCompanyNameRoot"
makecert -pe -a sha1 -n "CN=EmpTwoCodeSigning, OU=www.example.com, C=US" -b 01/01/2012 -e 01/01/2050 -eku 126.96.36.199.188.8.131.52.3 -ss My -is My -in "MyCompanyNameRoot"
Now lets export them so we can burn them onto a cd. You will need to find another utility on your windows computer called certmgr.exe. Run it. You will find all of the certificates installed on you computer, separated by category. The certificates just created are stored under the 'personal' tab. You will export each certificate twice, first will be a *.cer and the second a *.pfx. The *.cer will be your public key certificate, and the *.pfx will be your private/public key certificate that you must keep 'private'.
1. Select certificate and click export.
2. Choose 'do not export private key'
3. Choose 'Base-64 encoded X.509(.CER)'
4. Pick a file name such as c:\example.cer
5. Export and finish. This is your public certificate.
6. Select certifcate and click export.
7. Choose 'yes export the private key'
8. Choose 'Personal Information Exchange - PKCS #12(.PFX)
9. Choose a password to protect your private certificate.
10. Pick a file name such as c:\example.pfx
11. Export and finish. This is your private certificate.
Repeat the above steps for each certificate.
To sign your assemblies, open VS, and under the project signing tab, choose 'Sign the ClickOnce manifests' and then 'select from file'. You will be prompted for your password. Also choose 'Sign the assembly' and choose the same certificate. You will need to sign each project that is referenced in the application you wish to publish. The private key *.pfx file gets added to your project.
If you ever need to publish from a different computer, or you have re-formated your own computer, you will receive errors when you try to publish. This is because the password you typed to access your private certificate is stored in your windows user profile. Simply return to the project signing tab, reselect your certificate and type in the password again.
You can avoid some of the errors and warning about certificates on the client computer by installing your new 'public' root certificate, the *.cer file. This would be a good solution for a company using click once applications for internal use. Each developer that had a code signing certificate signed by your root certificate would automatically be trusted.
You can install certificates on a client machine by typing the following at the windows command prompt.
You can install the certificates using code as well. This example was written with VB.NET 2008.
certmgr.exe -add -all MyRootCerFileName.cer -s -r localMachine root
certmgr.exe -add -all MyEmpOneFileName.cer -s -r localMachine TrustedPublisher
certmgr.exe -add -all MyEmpTwoFileName.cer -s -r localMachine TrustedPublisher
You can view the certificates in a local store and even add a private key certificate using the following snippets.
Public Class installcerts
Private rootcert As New System.Security.Cryptography.X509Certificates.X509Certificate2("MyRootCerFileName.cer")
Private emp1cert As New System.Security.Cryptography.X509Certificates.X509Certificate2("MyEmpOneFileName.cer")
Private emp2cert As New System.Security.Cryptography.X509Certificates.X509Certificate2("MyEmpTwoFileName.cer")
Public Sub cert_Load()
Dim rs As New X509Store("root", StoreLocation.LocalMachine)
Dim store As New X509Store("TrustedPublisher", StoreLocation.LocalMachine)
'example to load a private key certificate
'Public privatecert As New System.Security.Cryptography.X509Certificates.X509Certificate2("privatekeyfilename.pfx", "certpassword")
'For Each cert As X509Certificate2 In store.Certificates