As individuals, it's important to have a way for others to easily verify our identity. One of the best ways to do this is by using a digital certificate for signing. Digital certificates can do many things, such as signing code.

Certificates are split into two parts, public and private keys. The public key needs to be made available online for others to download and trust. This way, when you sign content with your private key, others will see it as trusted.

What's subject and name?

The Subject and Friendly Name in a digital certificate are used to identify the certificate holder's information.

The Subject field contains information such as the certificate holder's name, organization, country, state/province, city, etc., which is used to verify the certificate holder's identity when using the digital certificate for encrypted communication or authentication. The system checks the Subject field to ensure the legitimacy of both parties in the communication.

The Friendly Name is an optional field that is typically used to name the certificate for easier identification and management by the user. It can be any user-defined string and does not affect the security or validity of the certificate.

For HTTPS certificates, the Subject field typically includes the domain name or hostname of the certificate holder. This is because HTTPS certificates are used to protect the security of web servers, and the identity of a web server is typically identified by its domain name or hostname.

In HTTPS communication, when a client initiates a connection request, the server sends its digital certificate to the client, which verifies the certificate's validity and checks whether the domain name or hostname in the Subject field matches the client's request. If the verification is successful, the client establishes a secure connection with the server to ensure the confidentiality and integrity of the communication.

Therefore, for HTTPS certificates, the domain name or hostname in the Subject field is crucial and must be accurate and legitimate. The Friendly Name can also be used to identify and manage the certificate, but it does not affect the security of HTTPS communication.

Generate your own self-signed certificate

Here's how to generate a self-signed certificate and obtain the private key:

$name = Read-Host "Please enter friendly name"
$subject = Read-Host "Please enter subject"
$password = Read-Host "Please enter pfx password" -AsSecureString

$cert = New-SelfSignedCertificate -Subject $subject `
                          -FriendlyName $name `
                          -Type CodeSigning `
                          -KeyUsage DigitalSignature `
                          -KeyLength 2048 `
                          -KeyAlgorithm RSA `
                          -HashAlgorithm SHA256 `
                          -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" `
                          -CertStoreLocation "Cert:\CurrentUser\My" 

$certPath = "cert:\CurrentUser\My\" + $cert.Thumbprint

Export-Certificate -Cert $certPath -FilePath "YourCert.cer"
Export-PfxCertificate -Cert $certPath -FilePath "YourCert.pfx" -Password $password

You will have two files: YourCert.cer and YourCert.pfx. Keep the .pfx safe! And make the YourCert.cer public for downloading.

file

Or course, if you are rich, buy one from:

  • Certum
  • Comodo
  • DigiCert
  • GlobalSign
  • SSL.com

It's hard to buy one if you are in China. Because they prefer to ship the cert to you. So I contacted sales in China.

The digital certificate salespeople in China were very reluctant to sell it to me. I kept explaining to him that I was only used to develop open source projects, so I reluctantly agreed to help me apply.

file

Trust your public key

If you are using your self-signed certificate, your friends are not trusing it by default. You need to manually distribute it to your friends.

And here's how to trust the public key:

# Run as Admin!
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import("C:\path\to\YourCert.cer")
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store("Root","LocalMachine")
$store.Open("MaxAllowed")
$store.Add($cert)
$store.Close()

Now your cert (public key) will be shown as trusted. The error icon will disappear.

file

By generating a self-signed certificate and distributing the public key, individuals can establish a level of trust with their clients and ensure that their communications are secure. This process is useful for developers and individuals who want to sign their own code and communications without relying on a third-party certificate authority.

Use your own cert to sign any exe!

Now you can sign your exe.

To use Signtool to sign a file, you need to first install the Microsoft Windows SDK. Then, you can follow these steps to sign the file:

  • Open a command prompt window.
  • Use the CD command to navigate to the directory where the Signtool.exe file is located (by default, this file is located in the "C:\Program Files (x86)\Windows Kits\10\bin\{YOUR_WINDOWS_VERSION}\x64\signtool.exe".
  • Enter the following command:
signtool sign /f .\PrivateKey.pfx /p "Password" /fd sha256 .\app.exe

Press Enter to execute the command. If the signing is successful, you will see the message "Successfully signed".

file

Congratulations! Now you can see that your binary is signed with a valid signature!

file

When it was trying to run as admin, you will see blue badge:

file

Use your own cert to sign nuget package

Now you can sign your binary. Right here assume you are a .NET developer and already built a C# project.

Pack your project first:

$ dotnet pack -c Release
MSBuild version 17.6.8+c70978d4d for .NET
  Determining projects to restore...
  All projects are up-to-date for restore.
  Aiursoft.CommandFramework -> C:\Users\xuef\source\repos\Anduin\HappyRecorder\src\Aiursoft.CommandFramework\bin\Release\net6.0\Aiursoft.CommandFramework.dll

Now sign it!

 $ dotnet nuget sign ./Aiursoft.CommandFramework.1.0.0.nupkg --certificate-path ~/Desktop/YourCert.pfx --certificate-password "password"  --timestamper http://timestamp.digicert.com

file

To verify if a NuGet package is signed, you can use the nuget verify command. Here's how:

$ dotnet nuget verify ./Aiursoft.CommandFramework.1.0.0.nupkg

This command will verify the package's signature and display the result. If the package is signed and the signature is valid, you will see a message indicating that the package is signed and the signature is valid. If the package is not signed or the signature is invalid, you will see an error message.

Additionally, you can also check the package's signature manually by opening it with an archive tool like 7-Zip and looking for the .signature.p7s file. This file contains the signature data, and you can use a tool like OpenSSL to verify the signature.

file

For more, please reference Nuget document: https://learn.microsoft.com/en-us/nuget/create-packages/sign-a-package.