概要
cscの作法、調べてみた。
サイトの証明書、叩いてみた。
sslstream使ってみた。
サンプルコード
using System;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.IO;
using System.Text;
public class Program {
private static void PrintCertificate(X509Certificate certificate) {
Console.WriteLine("===========================================");
Console.WriteLine("Subject={0}", certificate.Subject);
Console.WriteLine("Issuer={0}", certificate.Issuer);
Console.WriteLine("Format={0}", certificate.GetFormat());
Console.WriteLine("ExpirationDate={0}", certificate.GetExpirationDateString());
Console.WriteLine("EffectiveDate={0}", certificate.GetEffectiveDateString());
Console.WriteLine("KeyAlgorithm={0}", certificate.GetKeyAlgorithm());
Console.WriteLine("PublicKey={0}", certificate.GetPublicKeyString());
Console.WriteLine("SerialNumber={0}", certificate.GetSerialNumberString());
Console.WriteLine("===========================================");
}
private static Boolean RemoteCertificateValidationCallback(Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
PrintCertificate(certificate);
if (sslPolicyErrors == SslPolicyErrors.None)
{
Console.WriteLine("サーバー証明書の検証に成功しました\n");
return true;
}
else
{
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateChainErrors) == SslPolicyErrors.RemoteCertificateChainErrors)
{
Console.WriteLine("ChainStatusが、空でない配列を返しました");
}
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNameMismatch) == SslPolicyErrors.RemoteCertificateNameMismatch)
{
Console.WriteLine("証明書名が不一致です");
}
if ((sslPolicyErrors & SslPolicyErrors.RemoteCertificateNotAvailable) == SslPolicyErrors.RemoteCertificateNotAvailable)
{
Console.WriteLine("証明書が利用できません");
}
return false;
}
}
public static void Main() {
String hostName = "google.com";
Int32 port = 443;
using (TcpClient client = new TcpClient())
{
IPAddress[] ipAddresses = Dns.GetHostAddresses(hostName);
client.Connect(new IPEndPoint(ipAddresses[0], port));
using (SslStream sslStream = new SslStream(client.GetStream(), false, RemoteCertificateValidationCallback))
{
sslStream.AuthenticateAsClient(hostName);
Byte[] req = Encoding.ASCII.GetBytes(String.Format("GET / HTTP/1.0\r\nHost: {0}\r\n\r\n", hostName));
sslStream.Write(req);
sslStream.Flush();
Byte[] res = new Byte[1024];
Int32 n;
while ( (n = sslStream.Read(res, 0, res.Length) ) > 0)
{
String s = Encoding.ASCII.GetString(res, 0, n);
Console.WriteLine(s);
}
}
}
}
}
実行結果
>ssl4
===========================================
Subject=CN=*.google.com
Issuer=CN=GTS CA 1C3, O=Google Trust Services LLC, C=US
Format=X509
ExpirationDate=2022/08/29 17:29:45
EffectiveDate=2022/06/06 17:29:46
KeyAlgorithm=1.2.840.10045.2.1
PublicKey=0495DAEEDDFD96636B9E5D340384D2D1CE924A00BAA68EF50317E4F27C97DC39AAD327E9C2BDE4D63BB9B1721974BB6DF00BB34A1FC329222957A1D0A18911344C
SerialNumber=58ACE5940B417864129D531A39CB0067
===========================================
サーバー証明書の検証に成功しました
HTTP/1.0 301 Moved Permanently
Location: https://www.google.com/
Content-Type: text/html; charset=UTF-8
Date: Thu, 23 Jun 2022 01:13:05 GMT
Expires: Sat, 23 Jul 2022 01:13:05 GMT
Cache-Control: public, max-age=2592000
Server: gws
Content-Length: 220
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://www.google.com/">here</A>.
</BODY></HTML>
以上。