首先你得有一个证书和密钥,把它们转换成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();
}
}
}