Skip to content

Instantly share code, notes, and snippets.

@itn3000
Last active August 17, 2026 05:18
Show Gist options
  • Select an option

  • Save itn3000/61c6bb3d97e61e4fd446dbf2b0a8aca1 to your computer and use it in GitHub Desktop.

Select an option

Save itn3000/61c6bb3d97e61e4fd446dbf2b0a8aca1 to your computer and use it in GitHub Desktop.
how to send HTTPS request with client certificate in .NET 10
using System.Net.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using var cts = new CancellationTokenSource();
await Task.WhenAll(Task.Run(() =>
{
Console.ReadLine();
cts.Cancel();
}), RequestLoop(args[0], cts.Token));
Console.WriteLine("Hello, World!");
async Task RequestLoop(string url, CancellationToken ct)
{
var hoge = Environment.GetEnvironmentVariable("CERT_PASS");
// if using X509CertificateLoader.LoadPkcs12, 0x8009030D is raised when HttpClient.GetAsync
var clientCerts = X509CertificateLoader.LoadPkcs12Collection(File.ReadAllBytes("client.p12"), hoge, X509KeyStorageFlags.EphemeralKeySet);
var clientCert = clientCerts.First(x => x.HasPrivateKey);
using var clientHandler = new SocketsHttpHandler();
clientHandler.SslOptions.ClientCertificates = clientCerts;
clientHandler.SslOptions.CertificateRevocationCheckMode = X509RevocationMode.NoCheck;
clientHandler.SslOptions.LocalCertificateSelectionCallback = (sender, target, collection, remoteCert, acceptable) =>
{
Console.WriteLine($"target = {target},acceptable = {string.Join("|", acceptable)},remote={remoteCert?.Subject}");
return clientCert;
};
clientHandler.SslOptions.RemoteCertificateValidationCallback = (sender, x509, chain, policyError) =>
{
if (x509 != null)
{
Console.WriteLine($"remote x509 {x509.Subject}");
}
return true;
};
using var client = new HttpClient(clientHandler);
while (!ct.IsCancellationRequested)
{
try
{
using var res = await client.GetAsync(url, ct);
Console.WriteLine($"{res.StatusCode}");
var str = await res.Content.ReadAsStringAsync(ct);
Console.WriteLine($"response body: '{str}'");
}
catch (OperationCanceledException)
{
break;
}
catch (Exception e)
{
Console.WriteLine($"failed to request client: {e}");
}
try
{
await Task.Delay(10 * 1000, ct);
}
catch { }
}
// if X509Certificate2 is imported with not EphemeralKeySet and not disposed, secret key is remaining as garbage file in windows
foreach(var cert in clientCerts)
{
try
{
cert.Dispose();
} catch {}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment