Skip to content

Instantly share code, notes, and snippets.

@ereli
Last active April 20, 2024 08:48
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ereli/647f4ec9e014bc9cecfb843c764017ff to your computer and use it in GitHub Desktop.
Save ereli/647f4ec9e014bc9cecfb843c764017ff to your computer and use it in GitHub Desktop.
How to sign macOS and Windows executables using self-signed certificates on a Mac.

Signing MacOSX binaries

Generate certifcate

You will need to have code sign cert named Acme corp installed. Apple allows you to generate your certifcate using Keychain, follow this link for instructions.

Sign binaries

Once you have generate your certifcate, using the following command:

codesign -f -s "Acme Corp" hello --deep

Windows PE32 signing on a mac

Create CA and certificates

Generate a private key for the CA

openssl genrsa -out ca.key 4096

GHenerate certificate

openssl req -config openssl.cfg -new -x509 -days 1826 -key ca.key -out ca.crt -subj '/CN=Acme Corp CA'

Generate a private key for code siginig

openssl genrsa -out codesign.key 4096

Generate a new certificate request (csr) with just a CN.

openssl req -config openssl.cfg -new -key codesign.key -reqexts v3_req -out codesign.csr -subj '/CN=Acme Corp'

Create certificates based on the csr

openssl x509 -req -days 1826 -in codesign.csr -CA ca.crt -CAkey ca.key -extfile openssl.cfg -set_serial 01 -out codesign.crt

Export certificates based on the csr

openssl pkcs12 -export -out codesign.pfx -inkey codesign.key -in codesign.crt -passout pass:1

Install signcode

Make sure you have configured your npm

npm config set prefix ~/.local  

Also make sure ~/.local/bin is included in your path, then proceed to install signcode using npm.

npm install --global signcode

Sign the executable

Once you have generated your certifcate, you can use it with signcode to sign your Windows binary.

signcode sign hello.exe \
  --cert codesign.pfx \
  --prompt \
  --name 'Acme Corp's App' \
  --url 'http://AcmeCorp.corp'

After the file is signed you can do a very basic verification using

signcode verify hello.exe

Note that it would not say anything for a valid signature. An unsigned file will results in this error:

signcode verify hello.exe                                                                                                no signature found

Build binaries for testing

Install go

Make sure you have Go installed.

Build executables

Cross compile go binary on mac with windows target operating system.

set -x GOOS windows;set -x GOARCH 386; go build -o hello.exe hello.go

when you compile on macOS for native app, you don't need to set the GOOS variable. Unset the variable using set -e GOOS and then use go build -o hello hello.go to build the binary.

Bonus points

Use goversioninfo to embed some version information into the file.

package main
import "fmt"
func main() {
fmt.Println("hello world")
}
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[v3_req]
subjectKeyIdentifier=hash
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = codeSigning, msCodeInd, msCodeCom
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment