certutil: Decode Base64 Certs and Hash Files in CI
certutil -decode turns a base64 blob back into a file and certutil -hashfile computes a checksum, both built into Windows so CI needs no extra utilities.
certutil is a certificate tool, but its -decode and -hashfile modes make it a handy stand-in for base64 and sha256sum on bare Windows runners.
What it does
certutil -decode reads a base64 (PEM-style) file and writes the decoded bytes; -encode does the reverse. -hashfile prints a hash (default SHA1; pass an algorithm like SHA256). -addstore imports a cert into a Windows store.
Common usage
:: a CI secret holds a base64 PFX; restore it to a file
certutil -decode cert.b64 cert.pfx
:: hash an artifact with SHA-256
certutil -hashfile app.zip SHA256
:: import a CA cert into the machine Root store
certutil -addstore -f Root ca.cerOptions
| Flag | What it does |
|---|---|
| -decode <in> <out> | Base64-decode a file |
| -encode <in> <out> | Base64-encode a file |
| -hashfile <file> [algo] | Hash a file (SHA1 default; SHA256, MD5, ...) |
| -addstore <store> <cert> | Import a cert into a store (Root, My, CA) |
| -f | Force / overwrite without prompting |
In CI
When a secret stores a PFX or key as base64, certutil -decode reconstitutes it on the runner with no third-party tool. The header/footer for -decode can be a generic -----BEGIN CERTIFICATE----- or even absent; certutil tolerates plain base64 with surrounding lines.
Common errors in CI
"Cannot find the certificate and private key for decryption" or "The system cannot find the file specified. 0x80070002" usually means a wrong path. "Input length must be a multiple of 4" / "The specified base64 string is invalid" means the base64 was corrupted, often by CRLF/quote mangling when the secret was set; store it as a single clean base64 line. certutil -hashfile defaults to SHA1, so always pass SHA256 explicitly when comparing against a sha256 checksum.