From 0a2f3e4f2209bf417f810f7a741a69b44427ee02 Mon Sep 17 00:00:00 2001 From: DHR60 <192860629+DHR60@users.noreply.github.com> Date: Thu, 27 Aug 2026 07:31:39 +0000 Subject: [PATCH] Fix hy2 fmt (#10044) --- v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs | 5 +++ v2rayN/ServiceLib/Manager/CertPemManager.cs | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs b/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs index 8e12ecf4..7b7153e4 100644 --- a/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs +++ b/v2rayN/ServiceLib/Handler/Fmt/Hysteria2Fmt.cs @@ -223,6 +223,11 @@ public class Hysteria2Fmt : BaseFmt var sha = item.CertSha; dicQuery.Add("pinSHA256", Utils.UrlEncode(sha)); } + else if (!item.Cert.IsNullOrEmpty() + && CertPemManager.GetLeafCertSha256Thumbprint(item.Cert) is { Length: > 0 } thumbprint) + { + dicQuery.Add("pinSHA256", Utils.UrlEncode(thumbprint)); + } if (!item.EchConfigList.IsNullOrEmpty()) { dicQuery.Add("ech", Utils.UrlEncode(item.EchConfigList)); diff --git a/v2rayN/ServiceLib/Manager/CertPemManager.cs b/v2rayN/ServiceLib/Manager/CertPemManager.cs index adb48368..0df8301d 100644 --- a/v2rayN/ServiceLib/Manager/CertPemManager.cs +++ b/v2rayN/ServiceLib/Manager/CertPemManager.cs @@ -281,6 +281,37 @@ public class CertPemManager } } + public static string GetLeafCertSha256Thumbprint(string pemCertChain, bool includeColon = false) + { + var certs = ParsePemChain(pemCertChain); + if (certs.Count == 0) + { + return string.Empty; + } + foreach (var certStr in certs) + { + try + { + var cert = X509Certificate2.CreateFromPem(certStr); + var extension = cert.Extensions + .OfType() + .FirstOrDefault(); + var isCa = extension?.CertificateAuthority == true; + if (isCa) + { + continue; + } + var thumbprint = cert.GetCertHashString(HashAlgorithmName.SHA256); + return includeColon ? string.Join(":", thumbprint.Chunk(2).Select(c => new string(c))) : thumbprint; + } + catch + { + // Ignore + } + } + return string.Empty; + } + private static readonly Lazy _chromeRootCerts = new(() => { var pemText = EmbedUtils.GetEmbedText(Global.ChromeRootCertFileName);