[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-80545":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":16,"stars30d":17,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":19,"archived":20,"fork":20,"defaultBranch":21,"hasWiki":20,"hasPages":20,"topics":22,"createdAt":10,"pushedAt":10,"updatedAt":24,"readmeContent":25,"aiSummary":26,"trendingCount":15,"starSnapshotCount":15,"syncStatus":27,"lastSyncTime":28,"discoverSource":29},80545,"psign","Devolutions\u002Fpsign","Devolutions","Portable code signing tool","",null,"Rust",59,4,56,0,1,3,2.1,"MIT License",false,"master",[23],"architecture","2026-06-12 02:04:03","# psign\n\n`psign` is a **Rust port** of the Windows SDK **`signtool.exe`** behavior\n(sign, verify, timestamp, remove, and related Authenticode flows), validated with\ndifferential parity tests against the native tool where CI fixtures allow.\n\nCanonical repository: \u003Chttps:\u002F\u002Fgithub.com\u002FDevolutions\u002Fpsign>.\n\n## CLI surface\n\n- `verify`, `remove`, `catdb`: Windows-compatible `signtool.exe` flows backed by WinTrust and CryptSIP where native APIs are required.\n- `sign`: Rust mssign32 core (`SignerSignEx3`) with PFX\u002Fsystem-store cert selection, RFC3161 sign-time timestamping, first-class custom ZIP Authenticode support ([docs\u002Fzip-authenticode-signing.md](docs\u002Fzip-authenticode-signing.md)), and decoupled-digest bridge flow (`--dlib` or `--trusted-signing-dlib-root` + `--dmdf`) for MSIX parity and [Azure Artifact Signing \u002F Trusted Signing](docs\u002Fmigration-artifact-signing.md).\n- `inspect-signature`: JSON dump of PKCS#7 signers, timestamp OIDs, and nested signatures (`1.3.6.1.4.1.311.2.4.1`) — same parser as **`psign-tool portable inspect-authenticode`** ([docs\u002Fpsa-interoperability.md](docs\u002Fpsa-interoperability.md)).\n- `timestamp`: Rust mssign32 core (`SignerTimeStampEx3`\u002F`SignerTimeStampEx2`) plus AppX restrictions.\n- `rdp`: Rust port of **`rdpsign.exe`** for `.rdp` files (`SignScope` \u002F `Signature` records, detached PKCS#7 over the secure-settings blob).\n- `cert-store`: Portable file-backed certificate store under `~\u002F.psign\u002Fcert-store` by default, with Windows-style store\u002Fthumbprint selection.\n- `code`: dotnet\u002Fsign-style orchestration entry point. It supports `--dry-run` \u002F `--plan-json` planning over inputs, file lists, globs, and nested ZIP\u002FOPC containers, plus guarded local cert\u002Fkey, PFX, portable cert-store SHA-1, Azure Key Vault, or Artifact Signing execution for PE\u002FWinMD, NuGet\u002FSNuGet, VSIX, generic ZIP nested package entries, MSIX\u002FAppX unsigned-package prepare including nested packages inside upload\u002Fbundle containers, encrypted MSIX\u002FAppX OS-only diagnostics, ClickOnce `.manifest` \u002F `.application` \u002F `.vsto` XMLDSig signing, PE-like ClickOnce `.deploy` payloads, App Installer publisher updates + top-level or nested companion signatures, `--continue-on-error`, `--skip-signed`, `--overwrite`, and inside-out VSIX\u002FZIP -> NuGet\u002FVSIX -> PE\u002FClickOnce-manifest signing.\n- `portable ...`: Cross-platform digest, verification, trust, signing, package, RFC3161, and remote-hash helpers that avoid Win32 APIs, including PE\u002FWinMD signing through Azure Artifact Signing REST without Microsoft client DLLs.\n\n## MSIX parity notes\n\n- MSIX\u002FAppX signing requires `--timestamp-url` in the current parity profile.\n- Sign-time digest controls now distinguish file digest (`--digest`, native `\u002Ffd`) and RFC3161 timestamp digest (`--timestamp-digest`, native `\u002Ftd`).\n- Decoupled digest inputs (`--dlib` + `--dmdf`) are executed via a native-signature bridge path and parity-gated in CI scenarios.\n\n## Build\n\n```powershell\ncargo build\n```\n\nAt the repo root, **`cargo build`** targets **`default-members`**, including the unified **`psign-tool`** executable from `src\\main.rs` plus the portable digest \u002F trust \u002F package \u002F REST crates. On Windows, **`cargo build -p psign --bin psign-tool`** remains the explicit way to build only that executable. Default Cargo features include **`azure-kv-sign`** (Key Vault digest callback), **`artifact-signing-rest`** (**`artifact-signing-submit`** LRO against **`*.codesigning.azure.net`**), **`timestamp-http`** (portable RFC3161 HTTP POST), and **`timestamp-server`** (local RFC3161 test server); use **`--no-default-features`** for a minimal build.\n\n## Dotnet tool package from NuGet.org (.NET 10+)\n\n`psign-tool` is published as the RID-specific\n[`Devolutions.Psign.Tool`](https:\u002F\u002Fwww.nuget.org\u002Fpackages\u002FDevolutions.Psign.Tool)\ndotnet tool package:\n\n```powershell\ndotnet tool install -g Devolutions.Psign.Tool\npsign-tool --help\n```\n\nUpdate an existing global install:\n\n```powershell\ndotnet tool update -g Devolutions.Psign.Tool\n```\n\nOne-shot execution from NuGet.org:\n\n```powershell\ndotnet tool exec Devolutions.Psign.Tool -- --help\ndnx Devolutions.Psign.Tool --help\n```\n\nFor repository-local tool manifests, omit `-g`:\n\n```powershell\ndotnet new tool-manifest\ndotnet tool install Devolutions.Psign.Tool\ndotnet tool run psign-tool -- --help\n```\n\nCreate local dotnet tool packages from prebuilt release artifacts:\n\n```powershell\npwsh .\u002Fnuget\u002Fpack-psign-dotnet-tool.ps1 -Version 0.5.0 -ArtifactsRoot .\u002Fdist -OutputDir .\u002Fdist\u002Fnuget\n```\n\nThe package is built from native `psign-tool` artifacts for `win-x64`, `win-arm64`, `linux-x64`, `linux-arm64`, `osx-x64`, and `osx-arm64`, plus an `any` fallback package for unsupported runtimes.\n\n## Linux \u002F portable tooling\n\nThe canonical **`psign-tool`** CLI (package **`psign`**) supports an optional backend selector: **`--mode auto|windows|portable`**. When omitted, **`auto`** is used; **`PSIGN_TOOL_MODE`** can set the same default for parity automation. Windows mode uses Win32 APIs and registered SIP DLLs. Portable mode and the **`psign-tool portable ...`** namespace use the cross-platform Rust implementations from **`psign-sip-digest`**, **`psign-authenticode-trust`**, **`psign-opc-sign`**, **`psign-codesigning-rest`**, and **`psign-azure-kv-rest`** without **`WinVerifyTrust`** or the OS trust store.\n\n**Feature gaps vs native `signtool`, AzureSignTool, and Azure Artifact Signing:** [`docs\u002Fgap-analysis-signing-platforms.md`](docs\u002Fgap-analysis-signing-platforms.md). **Linux workflows (verify, REST hash sign, hybrid embed):** [`docs\u002Flinux-signing-pipelines.md`](docs\u002Flinux-signing-pipelines.md). For Key Vault **`RS256`** over CMS authenticated attributes (not the PE image hash), use **`psign-tool portable pe-signer-rs256-prehash`** — see [`docs\u002Fmigration-azuresigntool.md`](docs\u002Fmigration-azuresigntool.md).\n\nFrom the repo root (see [`docs\u002Froadmap-authenticode-linux.md`](docs\u002Froadmap-authenticode-linux.md)):\n\n```sh\ncargo build -p psign --bin psign-tool --locked\n# Portable RDP signing:\n# psign-tool portable rdp --cert cert.der --key key.pk8 file.rdp\n# Portable PE signing with a local RSA key:\n# psign-tool portable sign-pe --cert cert.der --key key.pk8 --output signed.exe unsigned.exe\n# Existing PE signatures are replaced by default; add --append-signature to match signtool \u002Fas.\n# Portable trust verification with explicit anchors:\n# psign-tool portable trust-verify-pe signed.exe --anchor-dir anchors\n# Portable custom ZIP Authenticode verification:\n# psign-tool portable trust-verify-zip archive.zip --anchor-dir anchors\n# Portable unsigned CAB signing with a local RSA key:\n# psign-tool portable sign-cab --cert cert.der --key key.pk8 --output signed.cab unsigned.cab\n# Portable MSI\u002FMSP signing with a local RSA key:\n# psign-tool portable sign-msi --cert cert.der --key key.pk8 --output signed.msi unsigned.msi\n# Portable generic catalog signing with a local RSA key:\n# psign-tool portable sign-catalog --cert cert.der --key key.pk8 --output files.cat file1.exe file2.txt\n# Portable RFC3161 timestamp token embedding after signing:\n# psign-tool portable timestamp-pe-rfc3161 signed.exe --response timestamp.tsr --output timestamped.exe\n# Portable package inspection helpers:\n# psign-tool portable nupkg-signature-info package.nupkg\n# psign-tool portable nupkg-digest package.nupkg --algorithm sha256\n# psign-tool portable nupkg-signature-content package.nupkg --output signature-content.txt\n# psign-tool portable nupkg-signature-pkcs7 package.nupkg --cert signer.der --key signer.pkcs8 --timestamp-url http:\u002F\u002Ftsa --timestamp-digest sha256 --output signature.p7s\n# psign-tool portable nupkg-signature-pkcs7-prehash package.nupkg --encoding raw --output prehash.bin\n# psign-tool portable nupkg-signature-pkcs7-from-signature package.nupkg --cert signer.der --signature remote.sig --output signature.p7s\n# psign-tool portable nupkg-verify-signature-content package.nupkg --content signature-content.txt\n# psign-tool portable nupkg-embed-signature package.nupkg --signature signature.p7s --output signed.nupkg\n# psign-tool portable nupkg-sign package.nupkg --cert signer.der --key signer.pkcs8 --timestamp-url http:\u002F\u002Ftsa --timestamp-digest sha256 --output signed.nupkg\n# psign-tool portable nupkg-verify-signature signed.nupkg --trusted-ca signer.der --allow-loose-signing-cert\n# psign-tool portable vsix-signature-info extension.vsix\n# psign-tool portable vsix-signature-reference-xml extension.vsix --output signature-reference.xml\n# psign-tool portable vsix-verify-signature-reference-xml extension.vsix --signature-xml signature-reference.xml\n# psign-tool portable vsix-signature-xml extension.vsix --cert signer.der --key signer.pkcs8 --output signature.xml\n# psign-tool portable vsix-signature-xml-prehash extension.vsix --encoding raw --output prehash.bin\n# psign-tool portable vsix-signature-xml-from-signature extension.vsix --cert signer.der --signature remote.sig --output signature.xml\n# psign-tool portable vsix-verify-signature-xml extension.vsix --signature-xml signature.xml --cert signer.der --trusted-ca root.der\n# psign-tool portable vsix-embed-signature-xml extension.vsix --signature-xml signature.xml --output signed.vsix\n# psign-tool portable vsix-sign extension.vsix --cert signer.der --key signer.pkcs8 --output signed.vsix\n# psign-tool portable vsix-verify-signature signed.vsix --trusted-ca root.der\n# psign-tool portable appinstaller-info app.appinstaller --signature app.appinstaller.p7\n# psign-tool portable appinstaller-sign-companion app.appinstaller --cert signer.der --key signer.pkcs8 --timestamp-url http:\u002F\u002Ftsa --timestamp-digest sha256 --output app.appinstaller.p7\n# psign-tool portable appinstaller-sign-companion-prehash app.appinstaller --encoding raw --output prehash.bin\n# psign-tool portable appinstaller-sign-companion-from-signature app.appinstaller --cert signer.der --signature remote.sig --output app.appinstaller.p7\n# psign-tool portable appinstaller-verify-companion app.appinstaller --signature app.appinstaller.p7 --anchor-dir anchors\n# psign-tool portable appinstaller-set-publisher app.appinstaller --publisher \"CN=Example\" --output updated.appinstaller\n# psign-tool portable business-central-app-info package.app\n# psign-tool portable msix-manifest-info package.msix\n# psign-tool portable msix-set-publisher package.msix --publisher \"CN=Example\" --output updated.msix\n# psign-tool portable clickonce-deploy-info app.exe.deploy\n# psign-tool portable clickonce-copy-deploy-payload app.exe.deploy --output app.exe\n# psign-tool portable clickonce-update-manifest-hashes app.exe.manifest --base-directory . --output updated.manifest\n# psign-tool portable clickonce-manifest-hashes updated.manifest --base-directory .\n# psign-tool portable clickonce-sign-manifest updated.manifest --cert signer.der --key signer.pkcs8 --output signed.manifest\n# psign-tool portable clickonce-sign-manifest-prehash updated.manifest --encoding raw --output prehash.bin\n# psign-tool portable clickonce-sign-manifest-from-signature updated.manifest --cert signer.der --signature remote.sig --output signed.manifest\n# psign-tool portable clickonce-verify-manifest-signature signed.manifest --trusted-ca signer.der\n# dotnet\u002Fsign-style dry-run planning for nested package orchestration:\n# psign-tool code --dry-run --plan-json --base-directory . --file-list files.txt\n# Initial guarded code execution for PE\u002FNuGet\u002FVSIX\u002FZIP\u002FMSIX\u002FClickOnce\u002FApp Installer inputs:\n# psign-tool code --base-directory . --cert signer.der --key signer.pkcs8 --output signed.exe app.exe\n# psign-tool code --base-directory . --pfx signer.pfx --password \"pfx-password\" --output signed.nupkg package.nupkg\n# psign-tool code --base-directory . --cert-store-dir ~\u002F.psign\u002Fcert-store --sha1 \u003Cthumbprint> --output signed.nupkg package.nupkg\n# psign-tool code --base-directory . --azure-key-vault-url https:\u002F\u002Fvault.vault.azure.net --azure-key-vault-certificate cert --azure-key-vault-accesstoken \"$TOKEN\" --output signed.nupkg package.nupkg\n# psign-tool code --base-directory . --artifact-signing-endpoint https:\u002F\u002Fwus2.codesigning.azure.net --artifact-signing-account-name acct --artifact-signing-profile-name profile --artifact-signing-access-token \"$TOKEN\" --output signed.nupkg package.nupkg\n# psign-tool code --base-directory . --cert signer.der --key signer.pkcs8 --timestamp-url http:\u002F\u002Ftsa --timestamp-digest sha256 --output signed.nupkg package.nupkg\n# psign-tool code --base-directory . --cert signer.der --key signer.pkcs8 --output signed.vsix extension.vsix\n# psign-tool code --base-directory . --overwrite --cert signer.der --key signer.pkcs8 --output resigned.nupkg signed-package.nupkg\n# psign-tool code --base-directory . --cert signer.der --key signer.pkcs8 --output signed.zip package-bundle.zip\n# psign-tool code --base-directory . --cert signer.der --key signer.pkcs8 --publisher-name \"CN=Publisher\" --output prepared.msix app.msix\n# psign-tool code --base-directory . --cert signer.der --key signer.pkcs8 --output signed.manifest app.exe.manifest\n# psign-tool code --base-directory . --cert signer.der --key signer.pkcs8 --output app.signed.exe.deploy app.exe.deploy\n# psign-tool code --base-directory . --cert signer.der --key signer.pkcs8 --publisher-name \"CN=Publisher\" --output updated.appinstaller.p7 app.appinstaller\n# Optional portable REST helpers (Linux\u002FmacOS):\n# cargo build -p psign --bin psign-tool --locked --features artifact-signing-rest\n# cargo build -p psign --bin psign-tool --locked --features azure-kv-sign\ncargo test -p psign-sip-digest -p psign-authenticode-trust -p psign-opc-sign -p psign-codesigning-rest -p psign-azure-kv-rest -p psign-digest-cli -p psign --locked\ncargo check -p psign-sip-digest -p psign-digest-cli -p psign-authenticode-trust -p psign-opc-sign -p psign-codesigning-rest -p psign-azure-kv-rest --locked\n```\n\nUnix CI (`ci-unix`) runs **`cargo fmt`**, strict **`clippy -D warnings`** on portable \u002F REST crates plus the **`psign` library**, and the digest CLI tests. Local mirror (bash): **`scripts\u002Flinux-portable-validation.sh`** from the repo root.\n\n## PowerShell portable Authenticode module\n\nThe repository also builds a PowerShell 7.4 \u002F .NET 8 module, **`Devolutions.Psign`**, with portable cmdlets backed by the Rust `psign_portable` shared library through P\u002FInvoke:\n\n```powershell\nImport-Module .\\PowerShell\\Devolutions.Psign\\Devolutions.Psign.psd1\nSet-PsignSignature -LiteralPath .\\script.ps1 -Certificate $cert\nGet-PsignSignature -LiteralPath .\\script.ps1\nSet-PsignSignature -LiteralPath .\\ModuleDirectory -CertificatePath .\\signer.cer -PrivateKeyPath .\\signer.key\nSet-PsignSignature -LiteralPath .\\package.msix -PfxPath .\\signer.pfx -Password $password\nSet-PsignSignature -LiteralPath .\\tool.exe -Sha1 $thumbprint -CertStoreDirectory .\\cert-store\nGet-PsignSignature -LiteralPath .\\tool.exe -TrustedCertificate $rootCertificate\n```\n\n`Set-PsignSignature` and `Get-PsignSignature` avoid Win32 SIPs and support PE, CAB, MSI, ZIP Authenticode, MSIX\u002FAppX, PowerShell scripts, whole PowerShell module directories (`.ps1`, `.psm1`, `.psd1`), content-mode signing, RFC3161 timestamping, chain embedding, portable cert-store thumbprint selection, and explicit-anchor trust verification. Their output remains portable-specific but exposes built-in-compatible `SignatureStatus` \u002F `SignatureType` properties for migration from `Get-AuthenticodeSignature`. See [`docs\u002Fportable-powershell-module.md`](docs\u002Fportable-powershell-module.md) and [`docs\u002Fportable-core-ffi.md`](docs\u002Fportable-core-ffi.md).\n\n## Portable certificate store\n\n`psign-tool cert-store ...` manages a simple file-based certificate store for portable workflows. The default base directory is **`~\u002F.psign\u002Fcert-store`**; set **`PSIGN_CERT_STORE`** or pass **`--cert-store-dir`** to override it. Certificates are stored as DER-encoded X.509 files named by Windows-style SHA-1 thumbprint over the full DER certificate. Optional local private keys live beside the certificate as PEM-encoded, unencrypted PKCS#8 **`.key`** files with the same thumbprint name.\n\n```text\n~\u002F.psign\u002Fcert-store\u002F\n  CurrentUser\u002F\n    MY\u002F\n      ABCDEF0123456789ABCDEF0123456789ABCDEF01.der\n      ABCDEF0123456789ABCDEF0123456789ABCDEF01.key\n    Root\u002F\n    CA\u002F\n  LocalMachine\u002F\n    MY\u002F\n    Root\u002F\n    CA\u002F\n```\n\nThe default scope is **`CurrentUser`**; **`--machine-store`** (native alias **`\u002Fsm`** on Windows) selects **`LocalMachine`** under the same base directory. The default store is **`MY`**; use **`--store`** (native alias **`\u002Fs`**) for stores such as **`Root`** or **`CA`**.\n\n```powershell\npsign-tool cert-store import --store MY cert.pem\npsign-tool cert-store import --store MY --key cert.key cert.der\npsign-tool cert-store import-pfx --store MY --password \"pfx-password\" cert.pfx\npsign-tool cert-store list --store MY\npsign-tool cert-store print --store MY --sha1 ABCDEF0123456789ABCDEF0123456789ABCDEF01\npsign-tool cert-store export --store MY --sha1 ABCDEF0123456789ABCDEF0123456789ABCDEF01 --out cert.der\npsign-tool cert-store export --store MY --sha1 ABCDEF0123456789ABCDEF0123456789ABCDEF01 --out cert.der --with-key --key-out cert.key\npsign-tool cert-store remove --store MY --sha1 ABCDEF0123456789ABCDEF0123456789ABCDEF01\n```\n\n`cert-store import-pfx` extracts the certificate and private key from a password-protected PFX\u002FPKCS#12 file but does not store the `.pfx` itself. `cert-store list` and `cert-store print` report whether a matching private key exists; they never print private key material.\n\nAfter importing a certificate and matching key, portable PE\u002FWinMD signing can use the same store\u002Fthumbprint selection shape as native signtool:\n\n```powershell\npsign-tool cert-store import-pfx --store MY --password \"pfx-password\" cert.pfx\npsign-tool --mode portable sign \u002Fsha1 ABCDEF0123456789ABCDEF0123456789ABCDEF01 \u002Fs MY \u002Ffd SHA256 file.exe\n```\n\nThe portable signing path supports local RSA\u002FSHA-2 Authenticode signing for PE\u002FWinMD plus the package\u002Fscript formats exposed by the portable core. Unsupported native signing options, CSP\u002FKSP selection, auto-selection, and non-exportable local keys return explicit errors in portable mode.\n\nCloud-backed signing options also accept Azure.Identity-style selectors:\n`--azure-key-vault-credential-type` and `--artifact-signing-credential-type`\n(`default`, `managed-identity`, `access-token`, `client-secret`,\n`workload-identity`). Managed identity maps to the existing managed-identity\nflows; workload identity is represented in provider planning but explicit\nsigning execution is not wired yet.\n\n## Generate binary manifest and dependency graph\n\n```powershell\ncargo run -p psign --bin psign-depgraph -- --signtool \"C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.26100.0\\x64\\signtool.exe\"\n```\n\nOutput files (gitignored **`parity-output\u002F`**):\n\n- `parity-output\u002Fbinary-manifest.json`\n- `parity-output\u002Fdependency-graph.json`\n\nComponent reference (**exe\u002FDLL roles**, SIP map, relationship diagram): [`docs\u002Fwindows-signing-components.md`](docs\u002Fwindows-signing-components.md).\n\n### Optional local copies of inbox signing binaries\n\n```powershell\n.\u002Fscripts\u002Fcopy-windows-signing-binaries.ps1\n# Optional: amd64 + WOW64 crypt32.dll (large).\n.\u002Fscripts\u002Fcopy-windows-signing-binaries.ps1 -IncludeCrypt32\n```\n\nWrites **`parity-output\u002Fvendor-binaries\u002F`** (WOW64 under **`syswow64\u002F`**): inbox SIP DLLs, **`imagehlp.dll`**, optional **`crypt32.dll`**, Office **`mso.dll`** \u002F **`VBE7.DLL`** when found, plus SDK **`mssign32.dll`** and **`signtool.exe`** when **Windows Kits\\10\\bin** is installed.\n\n## Run tests\n\n```powershell\ncargo fmt --all\ncargo clippy --workspace --all-targets --locked\ncargo test --workspace --locked\ncargo test --test parity_signtool -- --ignored --nocapture\n.\u002Fscripts\u002Frun-parity-diff.ps1 -FailOnSemantic\n```\n\n`-FailOnSemantic` requires `PSIGN_UNSIGNED_FIXTURE` and `PSIGN_TEST_PFX`. Add `-FailOnSemanticExhaustive` when timestamp, MSIX package, and detached PKCS#7 env vars are also set (see [`docs\u002Fci-parity.md`](docs\u002Fci-parity.md)).\n\n## CI parity (GitHub Actions)\n\nThe **`windows`** workflow builds the repo, bootstraps the public Devolutions test CA\u002FPFX (pinned raw URLs — no signing secrets), derives signed\u002Fdetached fixtures, packs a minimal unsigned MSIX, and runs `.\u002Fscripts\u002Fci\u002Frun-exhaustive-parity-ci.ps1`. Details and extension workflows live in [`docs\u002Fci-parity.md`](docs\u002Fci-parity.md). The workflow fails only on `semanticMismatchCount` in the generated **`parity-output\u002Fparity-report.json`** (that directory is gitignored; the JSON is a CI artifact or local output); rows classified `documented_*` (for example UTF-16 response files native cannot parse) do not fail the gate.\n\nLocal mirror of the CI orchestrator:\n\n```powershell\ncargo build -p psign --bin psign-tool\n.\u002Fscripts\u002Fci\u002Frun-exhaustive-parity-ci.ps1\n```\n\n## MSIX parity signing script\n\nUse the dedicated local parity runner to sign the same unsigned MSIX with native `signtool.exe` and `psign-tool`, then compare verification outcomes:\n\n```powershell\n$env:PSIGN_MSIX_UNSIGNED_FIXTURE=\"D:\\path\\unsigned.msix\"\n$env:PSIGN_MSIX_TEST_PFX=\"D:\\path\\authenticode-test-cert.pfx\"\n$env:PSIGN_MSIX_TEST_PFX_PASSWORD=\"CodeSign123!\"\n$env:PSIGN_MSIX_TIMESTAMP_URL=\"http:\u002F\u002Ftimestamp.digicert.com\"\n.\u002Fscripts\u002Fmsix-parity-sign.ps1 -FailOnSemantic\n```\n\nIf you already imported the Devolutions test cert into `CurrentUser\\\\My`, you can use thumbprint mode instead of a PFX:\n\n```powershell\n$env:PSIGN_MSIX_UNSIGNED_FIXTURE=\"D:\\path\\unsigned.msix\"\n$env:PSIGN_MSIX_TEST_CERT_SHA1=\"A9FDF3593E91689CC93B1CEBED5E8FFC1F6FEE38\"\n$env:PSIGN_MSIX_TIMESTAMP_URL=\"http:\u002F\u002Ftimestamp.digicert.com\"\n.\u002Fscripts\u002Fmsix-parity-sign.ps1 -FailOnSemantic\n```\n\nOptional decoupled digest parity:\n\n```powershell\n$env:PSIGN_MSIX_DLIB=\"D:\\path\\provider.dll\"\n$env:PSIGN_MSIX_DMDF=\"D:\\path\\metadata.json\"\n.\u002Fscripts\u002Fmsix-parity-sign.ps1 -UseDecoupledDigest -FailOnSemantic\n```\n\nReport artifact:\n\n- `parity-output\u002Fmsix-parity-sign-report.json`\n\nYou can also invoke the focused path through the main harness:\n\n```powershell\n.\u002Fscripts\u002Frun-parity-diff.ps1 -MsixOnly -FailOnSemantic\n```\n","psign是一个便携式的代码签名工具，用Rust语言实现，旨在复现Windows SDK中的signtool.exe功能。它支持签名、验证、时间戳、移除等操作，并且通过了与原生工具的差异性测试以确保一致性。项目提供了包括PE\u002FWinMD文件签名、ZIP Authenticode签名、MSIX\u002FAppX包准备及签名在内的多种功能，并支持PFX证书、系统存储证书以及Azure Key Vault等多种证书来源。此外，psign还具备跨平台特性，能在避免使用Win32 API的情况下完成大部分任务。该工具适用于需要在不同操作系统上进行代码签名和验证的开发者，特别是在构建和发布涉及复杂签名流程的应用程序时非常有用。",2,"2026-06-11 04:01:10","CREATED_QUERY"]