5d9aa02c07
- windows/win_card_reader.py: Windows-native card reader via the Raw Input API with a low-level keyboard-hook fallback. - windows/sign_exe.ps1: sign the built executable with a .pfx certificate. - windows/create_self_signed_cert.ps1: generate a self-signed cert for local testing (not trusted by Smart App Control). - windows/verify_sendinput_fix.py: verification helper for the SendInput foreground-unlock fix in run_win.py. - documentation/CODE_SIGNING_SMART_APP_CONTROL.md: signing guidance. - working_files/execute_playlist_retrieve.py, working_files/raw_server_playlist.json: playlist retrieval diagnostics. Note: windows/archive_list.txt and windows/build_last.txt are build output and were committed by request rather than by convention.
109 lines
4.1 KiB
Markdown
109 lines
4.1 KiB
Markdown
# Kiwy Signage Player — Code Signing & Smart App Control (Production)
|
||
|
||
> **TL;DR:** If production PCs have **Smart App Control (SAC) ON** and you
|
||
> cannot disable it, the player `.exe` **must be signed by a certificate from a
|
||
> reputable public CA**. There is no other way — SAC blocks unsigned binaries at
|
||
> the kernel level (no "Run anyway" button). Self-signed certs and Defender
|
||
> exclusions do **not** satisfy SAC.
|
||
|
||
---
|
||
|
||
## 1. Why Smart App Control blocks the app
|
||
|
||
- SAC (Windows 11 22H2+, "Smart App Control" in **Windows Security → App &
|
||
browser control**) only runs apps that are **signed by a reputable publisher**.
|
||
- Your locally-built `KiwySignagePlayer.exe` is **unsigned**
|
||
(`Get-AuthenticodeSignature` → `NotSigned`), so SAC refuses to launch it and
|
||
shows "An Application Control policy has blocked this file."
|
||
- Unlike classic SmartScreen, SAC has **no "Run anyway" button** and cannot be
|
||
bypassed per-file. Disabling SAC is **permanent** and only possible with admin
|
||
rights — so it is not viable for locked-down production PCs.
|
||
|
||
---
|
||
|
||
## 2. The solution for production: a real code-signing certificate
|
||
|
||
1. **Buy an OV code-signing certificate** from a reputable CA, e.g.:
|
||
- Sectigo Code Signing
|
||
- SSL.com Code Signing
|
||
- DigiCert Code Signing
|
||
- GlobalSign Code Signing
|
||
OV is sufficient for SAC; EV gives the highest trust level. Cost is roughly
|
||
USD 100–300/yr. The CA will issue a `.pfx`/`.p12` (or `.cer`+key).
|
||
|
||
2. **Sign the exe** after each build. Place your pfx at
|
||
`windows\kiwy_signing.pfx` (or set `KIWY_SIGN_PFX` env var) — `build_win.bat`
|
||
will then auto-sign via `sign_exe.ps1`:
|
||
|
||
```powershell
|
||
# One-off, from the windows\ folder:
|
||
.\sign_exe.ps1 -CertPath "C:\certs\mycodesign.pfx" -CertPassword "yourpwd"
|
||
```
|
||
|
||
The script:
|
||
- locates `signtool.exe` (Windows SDK) — install with
|
||
`winget install Microsoft.WindowsSDK.10.0.26100` if missing,
|
||
- signs with **SHA256** + **RFC3161 timestamp** (required for SAC and to
|
||
keep the signature valid after the cert expires),
|
||
- verifies the result with `Get-AuthenticodeSignature`.
|
||
|
||
3. **Test** — confirm on one production PC:
|
||
```powershell
|
||
Get-AuthenticodeSignature "dist\KiwySignagePlayer\KiwySignagePlayer.exe"
|
||
# Status must be: Valid
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Dev / test machines (where you have admin rights)
|
||
|
||
If a test PC has SAC **off**, you can make the app trusted locally without
|
||
buying a cert:
|
||
|
||
```powershell
|
||
# Run as Administrator
|
||
.\create_self_signed_cert.ps1
|
||
```
|
||
|
||
This creates a self-signed code-signing cert, exports `kiwy_dev_signing.pfx`,
|
||
and installs it into **Trusted Root + Trusted Publisher + Trusted People** for
|
||
the current user, so the player runs without SmartScreen/Defender prompts on
|
||
that dev PC.
|
||
|
||
⚠️ **This does NOT satisfy SAC.** It is only for machines where SAC is off or
|
||
where you have admin rights.
|
||
|
||
---
|
||
|
||
## 4. Build → sign → verify workflow
|
||
|
||
```bat
|
||
:: 1. Build (produces dist\KiwySignagePlayer\KiwySignagePlayer.exe)
|
||
cd windows
|
||
venv\Scripts\python.exe -m PyInstaller build.spec --clean --noconfirm
|
||
|
||
:: 2. Sign (auto if kiwy_signing.pfx present, else manual)
|
||
.\sign_exe.ps1 -CertPath "C:\certs\mycodesign.pfx" -CertPassword "..."
|
||
|
||
:: 3. Verify
|
||
Get-AuthenticodeSignature "dist\KiwySignagePlayer\KiwySignagePlayer.exe"
|
||
```
|
||
|
||
`build_win.bat` now does step 1 + step 2 automatically when a pfx is present.
|
||
|
||
---
|
||
|
||
## 5. Important caveats
|
||
|
||
- **Timestamping is mandatory.** The sign script timestamps by default
|
||
(`http://timestamp.digicert.com`). Without a timestamp, the signature becomes
|
||
invalid once the certificate expires and SAC will block the app.
|
||
- **SAC reputation takes time.** Even a validly signed exe from a brand-new
|
||
certificate may be blocked until the CA's reputation builds. EV certificates
|
||
and well-known CAs (DigiCert, Sectigo, SSL.com) pass immediately.
|
||
- **Re-sign after every build.** PyInstaller creates a new exe each time; the
|
||
old signature is lost. The auto-sign step in `build_win.bat` handles this.
|
||
- **Do not use UPX** on the signed exe — it invalidates the signature and can
|
||
trigger false positives. (`upx=True` in the spec currently does nothing
|
||
because UPX is not installed; if you ever install UPX, set it to False.)
|