using System.Security.Cryptography; using System.Text; namespace BSO.Launcher; /// /// Prueft die Signatur von Mod-, Server- und Launcher-Releases (wie bei MSCO). tools\release.ps1 signiert /// "BSO-RELEASE|produkt|version|sha256" mit dem privaten Release-Schluessel (liegt nur beim Entwickler, DPAPI-verschluesselt); /// hier ist nur der oeffentliche Schluessel eingebaut (eingetragen von tools\new-release-key.ps1). Ohne gueltige Signatur /// wird nichts installiert - selbst wer den Master oder den Release-Token uebernimmt, kann keine fremde Datei verteilen. /// public static class ReleaseSignature { const string PublicKey = "mWnJlmK+ZHcbVdN+AEvB2pU8cYLmIAygylltXK7/Gb6Qs0vDlOK9vrXy8+Yx0//WkWrV2pgvuPErlnmwCdHp5RTEr4whXqfGXs2KphQD7wI7kSAA9ETUULgztv4oaW8ndmaAJvBdnLVF3IB0snH51abd0Y+JCnQ/64J8CP0zECdoLFebmGP6wYV75oZrNh9v9EqaQ3qH56SnwUH8dFoR7nkoi6M2o+S1/pL4hTpBGMWmm1DJXsck4HJTlblEDPkT9ksgJf9oj3aZrLGwne+ZOLQ+DJF1SDmFT75bWPUvW8WP4TJnG85epn7JwsKLFNy2wb2UtJLAdF+KCIgefnQU/qXvSYRg/LIWxX9FVysQW2re1dcm+kI+NLddA88i6xpi7Ziste0NzyKD6SnaEP8fNVuoobpgW+S8Gfq7pemxA9/EibqXdyCbsT+IHF5SaEHU6EbC50bRF2ssoMevf2pPv/6omgHaT1BUiQPEetMEx0HOzcnMlmVNk6hNkiXBngopAQAB"; /// Text, der signiert wird: passt nur zu genau dieser Datei, diesem Produkt und dieser Version. public static string Message(string product, string version, string sha256) => $"BSO-RELEASE|{product}|{version}|{sha256.ToLowerInvariant()}"; public static bool Verify(string product, string version, string sha256, string? signature) { if (string.IsNullOrWhiteSpace(signature)) return false; try { using var rsa = RSA.Create(); rsa.FromXmlString(PublicKey); return rsa.VerifyData(Encoding.UTF8.GetBytes(Message(product, version, sha256)), Convert.FromBase64String(signature), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); } catch { return false; } } }