備忘録

備忘録

C# HttpListenerでhttps

1. オレオレ証明書を作る

makecert -n "CN=localhostCA" -r -pe -sv localhostCA.pvk localhostCA.cer
makecert -pe -iv localhostCA.pvk -n "CN=localhost" -ic localhostCA.cer -sv localhostSignedByCA.pvk localhostSignedByCA.cer
pvk2pfx -pvk localhostSignedByCA.pvk -spc localhostSignedByCA.cer -pfx localhostSignedByCA.pfx

複数のファイルが生成されるが localhostSignedByCA.pfx だけ使う。
※この時パスワードは任意のもの

2. localhostSignedByCA.pfx を登録する。

localhostSignedByCA.pfx をダブルクリックしてウィザードに従うだけ。
※この時パスワードは無し

3. netsh を使い SSL 証明書のバインドを追加する
netsh http add sslcert ipport=0.0.0.0:443 certhash=「localhostSignedByCA.cer の 拇印」 appid={「アプリケーションのGUID」}

例.

netsh http add sslcert ipport=0.0.0.0:443 certhash=749f2ed3c9b62376ab9ecf344e6e705ef5b8b702 appid={707a9d9a-bc90-426d-a09a-9477511a9fc1}

以上です。
C#のプログラムを書く必要はありません。

削除したくなった時

1. mmcで証明書の管理(ローカルコンピュータ)を起動する。
※ユーザーの方ではない
2. 個人\証明書\localhost を削除
netsh http delete sslcert ipport=0.0.0.0:443

また、アプリ配布時など、ユーザーに2〜3の手順を行ってもらう必要がありますが、
ユーザーが詳しくない場合はアプリケーション側で2〜3を書く事が可能です。

2〜3の手順をC#のコードで書く場合

private void AddCert()
{
  var certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);

  var cert = new X509Certificate2(
    "localhostSignedByCA.pfx"
    , ""
    , X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet);

  Console.WriteLine();

  certStore.Open(OpenFlags.ReadWrite);

  if (!certStore.Certificates.Contains(cert))
  {
    certStore.Add(cert);

    // 自分(このアプリケーション)の Guidを取得する
    var assem = System.Reflection.Assembly.GetExecutingAssembly();
    var guid = (Attribute.GetCustomAttribute(assem, typeof(System.Runtime.InteropServices.GuidAttribute)) as System.Runtime.InteropServices.GuidAttribute).Value;

    Process.Start(new ProcessStartInfo()
    {
      FileName = "netsh",
      Arguments = $"http add sslcert ipport=0.0.0.0:443 certhash={BitConverter.ToString(cert.GetCertHash()).Replace("-", "")} appid={{{guid}}}"
    });
  }

  certStore.Close();
}