diff --git a/README.md b/README.md index e853415..3f58801 100644 --- a/README.md +++ b/README.md @@ -74,15 +74,18 @@ tests/Metin2Launcher.Tests/ game assets (~4 GB) are handled by our own patcher code. - **xunit / xunit.runner.visualstudio** — tests. -## PLACEHOLDER public key +## Signing key -`LauncherConfig.PublicKeyHex` currently contains a **test-only** Ed25519 public -key generated locally during MVP scaffolding: +`LauncherConfig.PublicKeyHex` is the Ed25519 public key that every manifest +must verify against: ``` -a8619c11348cb26cdcad9467c5dd44e3fcb40017e9fbcf225ac76ad824422c46 +1d2b63751ea0e0354d28e7eb4ec175919a01518b0bcf5878f0a3aa8e7c6ce2bc ``` -This MUST be replaced with the real production signing key before the first -public release. The private half of this placeholder was used only to prove -signature wiring works; it is not tied to any real release. +The matching private key lives only on the release machine at +`~/.config/metin/launcher-signing-key` with `chmod 600`, is never committed +to any repo, and is used by `scripts/sign-manifest.py` in the `m2dev-client` +repo to sign `manifest.json` before upload. Rotation is done by shipping a +new launcher binary that embeds the new public key; the rotation flow is +documented in `m2dev-client/docs/update-manager.md`. diff --git a/src/Metin2Launcher/Config/LauncherConfig.cs b/src/Metin2Launcher/Config/LauncherConfig.cs index afc8c53..8125a43 100644 --- a/src/Metin2Launcher/Config/LauncherConfig.cs +++ b/src/Metin2Launcher/Config/LauncherConfig.cs @@ -16,12 +16,13 @@ public static class LauncherConfig /// /// Ed25519 public key used to verify the manifest signature. /// - /// PLACEHOLDER — generated with NSec.Cryptography during MVP scaffolding. - /// Must be swapped for the real production key before first public release. - /// The matching private key lives only in the test-generator used locally and - /// IS NOT used to sign any real release. + /// The matching private key lives offline in ~/.config/metin/launcher-signing-key + /// (chmod 600) on the release machine and is never committed to any repo. + /// Manifests are signed with scripts/sign-manifest.py in the m2dev-client repo. + /// Rotation is done by shipping a new launcher binary that embeds the new public + /// key; see docs/update-manager.md for the rotation flow. /// - public const string PublicKeyHex = "a8619c11348cb26cdcad9467c5dd44e3fcb40017e9fbcf225ac76ad824422c46"; + public const string PublicKeyHex = "1d2b63751ea0e0354d28e7eb4ec175919a01518b0bcf5878f0a3aa8e7c6ce2bc"; public static readonly TimeSpan ManifestFetchTimeout = TimeSpan.FromSeconds(10); public static readonly TimeSpan BlobFetchTimeout = TimeSpan.FromSeconds(60);