JBrowser Source Docs
You are reading the documentation for JBrowser 1.5.1. The newest release is 1.5.4. Go to the latest documentation

Code signing and SmartScreen

New in 1.5.1 When someone downloads JBrowser-Setup-<version>.exe with a browser and runs it, Windows SmartScreen can stop it with "Windows protected your PC". The build can sign JBrowser's programs with a code-signing certificate; this page explains what that does and doesn't change.

Why the warning appears#

SmartScreen checks programs that carry the Mark-of-the-Web, the tag browsers add to downloaded files (extracting a downloaded zip passes it on). A program runs without a warning when it has a reputation: enough people have run it, or it is signed with a certificate that has.

Situation Warning?
Unsigned installer, downloaded with a browser Yes, until that exact file has been run by enough people. Every release is a new file and starts again.
Signed with a certificate from a trusted certificate authority At first, sometimes. The reputation belongs to the certificate, so it builds up over releases and new versions inherit it.
Signed with a self-signed certificate Yes: Windows doesn't trust the certificate.
Installed with the one-command install (install.ps1) No: PowerShell's download has no Mark-of-the-Web, and the script removes it after checking the SHA-256.
Updated by JBrowser's updater No: the installer is checked against its SHA-256 and run without the Mark-of-the-Web.

EV certificates no longer skip the reputation stage (since 2024). With Smart App Control on (a Windows 11 option, off on most PCs), unsigned programs are blocked outright.

Getting a certificate#

Every option checks the publisher's identity first, so it has to be requested by the project's owner. docs/SIGNING.md compares them: SignPath Foundation (free for open-source projects, for builds made by CI), Certum Open Source Code Signing (from about €69, on a smart card), Azure Artifact Signing (US$9.99 a month; individuals in the USA and Canada only) and commercial OV certificates. A Microsoft Store listing (MSIX, signed by the Store) avoids SmartScreen entirely.

How the build signs#

tools/sign.ps1 does the signing. It is called for:

File Called by
dist\JBrowser\JBrowser.exe tools\build_app.ps1, right after PyInstaller
the uninstaller inside Setup Inno Setup, while compiling (SignedUninstaller=yes)
JBrowser-Setup-<version>.exe Inno Setup, at the end; the .sha256 is written after it

tools\build_installer.ps1 asks sign.ps1 -Status whether a certificate is configured. If one is, it passes /DSignSetup (which turns on SignTool=jbsign in installer/JBrowser.iss) and defines the jbsign tool as powershell.exe -File tools\sign.ps1 $f. With nothing configured, sign.ps1 does nothing and builds are unsigned.

The certificate comes from environment variables:

Variable Meaning
JBROWSER_SIGN_THUMBPRINT SHA-1 thumbprint of a certificate in Cert:\CurrentUser\My or Cert:\LocalMachine\My, including hardware tokens and cloud HSMs
JBROWSER_SIGN_PFX, JBROWSER_SIGN_PFX_PASSWORD a .pfx file and its password
JBROWSER_SIGN_AZURE, JBROWSER_SIGN_AZURE_DLIB Azure Artifact Signing: metadata.json and Azure.CodeSigning.Dlib.dll
JBROWSER_SIGN_TIMESTAMP a timestamp server (default: DigiCert, then Sectigo, then GlobalSign)
JBROWSER_SIGN_TEST=1 accept an untrusted (self-signed) certificate, for testing; master.ps1 -Publish refuses to run with it
$env:JBROWSER_SIGN_THUMBPRINT = "0123456789ABCDEF0123456789ABCDEF01234567"
.\tools\sign.ps1 -Status          # the certificate and tool that will be used
.\master.ps1 -Version 1.5.2 -Publish

sign.ps1 uses signtool.exe from the Windows SDK when it is installed (required for Azure), and otherwise Set-AuthenticodeSignature. Signatures are SHA-256 and timestamped, so they stay valid after the certificate expires. Timestamp servers are retried, and each file is checked afterwards: the signature must be Valid (or, in test mode, present and made by the configured certificate).

master.ps1 shows before building whether signing is configured, and afterwards whether Setup is signed. A signed build's release notes and INSTALL.txt name the publisher instead of explaining the SmartScreen warning.

PyInstaller and signing

Signing appends a certificate table to JBrowser.exe. PyInstaller's bootloader finds its archive from the end of the file and copes with that; a signed build starts normally. Check with a throw-away profile after changing how the exe is built.

Testing without a real certificate#

Create a self-signed code-signing certificate in memory and export it as a .pfx (CertificateRequest in .NET), so nothing is added to Windows' certificate stores. Then set JBROWSER_SIGN_PFX, JBROWSER_SIGN_PFX_PASSWORD and JBROWSER_SIGN_TEST=1, build or sign a copy, check Get-AuthenticodeSignature (it reports UnknownError: the certificate isn't trusted), and delete the .pfx. Never publish a build signed this way.