C#ssl使用自定义的crt证书和key密钥

首先你得有一个证书和密钥,把它们转换成windows支持的pfx格式证书,这个证书就带有密钥

在线转换

https://zhuanlan.zhihu.com/p/100719798

或者linux命令转换(需要安装openssl)

openssl pkcs12 -export -out test.pfx -inkey test.key -in test.crt

之后去这里导入证书,导入证书要选择我的用户账户,不能选择我的计算机账户,不然下次重启证书就失效

https://jingyan.baidu.com/article/e4511cf35b47fa2b855eaf5d.html

前奏工作做完,就可以做接下来的事情了。(mmc导入证书不保存,一段时间后会失效)

源码参考

https://www.cnblogs.com/tuyile006/p/13341033.html

的单向认证

这里精简了ssl的代码,仅供测试,不保证不会出错。

客户端代码如下

警告:中间有个ValidateServerCertificate函数,如果证书认证失败就会调用这个函数(如果是官方认证的证书就不会出现这种情况),如果返回false就会导致ssl通信无法进行下去,如果你的证书打开就是——不能保证该证书完整性,推荐把返回值都改为true。

需要改的地方:IP、端口号、证书认证方(TestServer)

namespace ConsoleAppClient
{
    using System;
    using System.Collections;
    using System.Net.Security;
    using System.Net.Sockets;
    using System.Security.Authentication;
    using System.Text;
    using System.Security.Cryptography.X509Certificates;
    namespace Examples.System.Net
    {
        public class SslTcpClient
        {

            public static bool ValidateServerCertificate(
                  object sender,
                  X509Certificate certificate,
                  X509Chain chain,
                  SslPolicyErrors sslPolicyErrors)
            {
                if (sslPolicyErrors == SslPolicyErrors.None)
                    return true;
                Console.WriteLine("Certificate error: {0}", sslPolicyErrors);

                return false;
            }

            public static void RunClient()
            {

                TcpClient client = new TcpClient("127.0.0.1", 10001);
                Console.WriteLine("Client connected.");

                SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
                try
                {
                    //根据绝对路径导入证书,服务端也类似,pfx的证书制作可以百度
                    //X509Certificate2Collection certs = new X509Certificate2Collection();
                    //certs.Import(@"C:\\TestServer.pfx", "password",X509KeyStorageFlags.DefaultKeySet);
                    //sslStream.AuthenticateAsClient("TestServer", certs, SslProtocols.Tls12, false);
                    sslStream.AuthenticateAsClient("TestServer");
                }
                catch (AuthenticationException e)
                {
                    Console.WriteLine("Exception: {0}", e.Message);
                    if (e.InnerException != null)
                    {
                        Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                    }
                    Console.WriteLine("Authentication failed - closing the connection.");
                    client.Close();
                    return;
                }

                byte[] messsage = Encoding.UTF8.GetBytes("Hello from the client.<EOF>");
                sslStream.Write(messsage);
                sslStream.Flush();
                client.Close();
            }


            public static void Main(string[] args)
            {

                try
                {
                    RunClient();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                Console.ReadLine();
            }
        }
    }
}

服务端代码

需要改的地方:IP、端口号、证书认证方(TestServer)

using System;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Text;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;

namespace ConsoleApp
{
    public class Program
    {
        static X509Certificate serverCertificate = null;

        static void ProcessClient(TcpClient client)
        {
            SslStream sslStream = new SslStream(client.GetStream(), false);

            sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls, true);
            sslStream.ReadTimeout = 5000;
            sslStream.WriteTimeout = 5000;

            while (true)
            {
                string messageData = ReadMessage(sslStream);
                if (messageData == "")
                    break;
                Console.WriteLine("Received: {0}", messageData);
            }

            sslStream.Close();
            client.Close();
        }
        static string ReadMessage(SslStream sslStream)
        {
            byte[] buffer = new byte[2048];
            StringBuilder messageData = new StringBuilder();
            int bytes = -1;
            do
            {
                bytes = sslStream.Read(buffer, 0, buffer.Length);
                Decoder decoder = Encoding.UTF8.GetDecoder();
                char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
                decoder.GetChars(buffer, 0, bytes, chars, 0);
                messageData.Append(chars);
                if (messageData.ToString().IndexOf("") != -1)
                {
                    break;
                }
            }
            while (bytes != 0);

            return messageData.ToString();
        }
        public static void Main(string[] args)
        {
            try
            {
                X509Store store = new X509Store(StoreName.Root);
                store.Open(OpenFlags.ReadWrite);
                // 检索证书 
                X509Certificate2Collection certs = store.Certificates.Find(X509FindType.FindBySubjectName, "TestServer", false); // vaildOnly = true时搜索无结果。
                if (certs.Count == 0) return;

                serverCertificate = certs[0];

                TcpListener listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 10001);
                listener.Start();

                Console.WriteLine("Waiting for a client to connect...");
                TcpClient client = listener.AcceptTcpClient();
                ProcessClient(client);

                store.Close(); // 关闭存储区。
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadLine();
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值