C# ssl/tls with socket tcp
本文关键字:socket tcp with tls ssl | 更新日期: 2023-09-27 18:05:22
我是c#开发新手。我试图在tcp上使用ssl/tls,但在我的代码中,system.net.sockets.socket(裸套接字)使用的不是tcpclient或tcplistner。我已经在网上搜索了至少200个链接,但我没有得到任何相关的东西。我想使用更少的编码和完成ssl或tsll在tcp套接字连接。我有客户端,服务器,ca证书,密钥在。key格式。请提供示例或链接。
为什么不使用TcpClient
?与TcpClient
和Ssltream
创建SSL连接非常简单。除非您需要数千个同时连接,否则我将坚持使用TcpClient
和SSLStream
。
TcpClient
和SslStream
的基本示例如下:
static void Main(string[] args)
{
string server = "127.0.0.1";
TcpClient client = new TcpClient(server, 443);
using (SslStream sslStream = new SslStream(client.GetStream(), false,
new RemoteCertificateValidationCallback(ValidateServerCertificate), null))
{
sslStream.AuthenticateAsClient(server);
// This is where you read and send data
}
client.Close();
}
public static bool ValidateServerCertificate(object sender, X509Certificate certificate,
X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
在。net中编写高性能的套接字代码是很困难的,但是有一些很好的例子。你有很多选择。我不确定一个解决方案适合所有,所以我在这里列出一些。
- 使用[异步客户端套接字]可能是一个很好的开始
- 有一些现有的库可以使用。我使用过Nito/Async,但我认为它自2009年以来没有更新过。有关于版本2的讨论,但我不相信它实现了。
- 我不熟悉它,但CodeProject有c# SocketAsyncEventArgs高性能Socket代码
- 回顾微软的指导,高性能。net套接字服务器使用异步Winsock
- 阅读Stephen Toub必须说的所有内容,包括等待套接字操作
我没有特别提到SSL,而是研究了SslStream
类。
您还需要查看缓冲池。如果您为数千个客户机提供服务,那么垃圾收集将是一个问题。Sunny Ahuwanya的博客是一个很好的介绍
https://github.com/StephenCleary/AsyncEx
。
您应该能够使用System.Net.Sockets.NetworkStream
来封装套接字,然后使用System.Net.Security.SslStream
来封装网络流。
Socket socket;
Stream networkStream = new NetworkStream(socket);
Stream sslStream = new SslStream(networkStream);
这是给你的
public class SSL
{
private bool CertificateValidationCallback(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
return true;
}
public class Certificate
{
public System.Security.Cryptography.X509Certificates.X509Certificate2 GetCertificate()
{
string certificatePath = @"D:'Rayan Ab Niro'Projecr'VPN'WindowsVPN'SSL.pfx"; //ConfigurationManager.AppSettings["certificatePath"].ToString();
var stream = File.OpenRead(certificatePath);
return new System.Security.Cryptography.X509Certificates.X509Certificate2(ReadStream(stream), "mypassword", System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.MachineKeySet | System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable);
}
private byte[] ReadStream(Stream input)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
}
public System.Net.Security.SslStream GetStream(NetworkStream _NetworkStream)
{
try
{
System.Net.Security.SslStream sslStream = new System.Net.Security.SslStream(_NetworkStream, false,);
sslStream.AuthenticateAsServer(serverCertificate, clientCertificateRequired: false,
enabledSslProtocols:
System.Security.Authentication.SslProtocols.Default |
System.Security.Authentication.SslProtocols.None |
System.Security.Authentication.SslProtocols.Tls |
System.Security.Authentication.SslProtocols.Tls11 |
System.Security.Authentication.SslProtocols.Tls12 |
System.Security.Authentication.SslProtocols.Ssl2 |
System.Security.Authentication.SslProtocols.Ssl3
, checkCertificateRevocation: true);
new SSL().DisplaySecurityLevel(sslStream);
new SSL().DisplaySecurityServices(sslStream);
new SSL().DisplayCertificateInformation(sslStream);
new SSL().DisplayStreamProperties(sslStream);
sslStream.ReadTimeout = 5000;
sslStream.WriteTimeout = 5000;
return sslStream;
}
catch (Exception ex)
{
throw ex;
}
}
public string ReadMessage(System.Net.Security.SslStream sslStream)
{
// Read the message sent by the client.
// The client signals the end of the message using the
// "<EOF>" marker.
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
//do
//{
// Read the client's test message.
bytes = sslStream.Read(buffer, 0, buffer.Length);
// Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
// Check for EOF or an empty message.
if (messageData.ToString().IndexOf("<EOF>") != -1)
{
//break;
}
//} while (bytes != 0);
return messageData.ToString();
}
public void DisplaySecurityLevel(System.Net.Security.SslStream stream)
{
Console.WriteLine("Cipher: {0} strength {1}", stream.CipherAlgorithm, stream.CipherStrength);
Console.WriteLine("Hash: {0} strength {1}", stream.HashAlgorithm, stream.HashStrength);
Console.WriteLine("Key exchange: {0} strength {1}", stream.KeyExchangeAlgorithm, stream.KeyExchangeStrength);
Console.WriteLine("Protocol: {0}", stream.SslProtocol);
}
public void DisplaySecurityServices(System.Net.Security.SslStream stream)
{
Console.WriteLine("Is authenticated: {0} as server? {1}", stream.IsAuthenticated, stream.IsServer);
Console.WriteLine("IsSigned: {0}", stream.IsSigned);
Console.WriteLine("Is Encrypted: {0}", stream.IsEncrypted);
}
public void DisplayStreamProperties(System.Net.Security.SslStream stream)
{
Console.WriteLine("Can read: {0}, write {1}", stream.CanRead, stream.CanWrite);
Console.WriteLine("Can timeout: {0}", stream.CanTimeout);
}
public void DisplayCertificateInformation(System.Net.Security.SslStream stream)
{
Console.WriteLine("Certificate revocation list checked: {0}", stream.CheckCertRevocationStatus);
System.Security.Cryptography.X509Certificates.X509Certificate localCertificate = stream.LocalCertificate;
if (stream.LocalCertificate != null)
{
Console.WriteLine("Local cert was issued to {0} and is valid from {1} until {2}.",
localCertificate.Subject,
localCertificate.GetEffectiveDateString(),
localCertificate.GetExpirationDateString());
}
else
{
Console.WriteLine("Local certificate is null.");
}
// Display the properties of the client's certificate.
System.Security.Cryptography.X509Certificates.X509Certificate remoteCertificate = stream.RemoteCertificate;
if (stream.RemoteCertificate != null)
{
Console.WriteLine("Remote cert was issued to {0} and is valid from {1} until {2}.",
remoteCertificate.Subject,
remoteCertificate.GetEffectiveDateString(),
remoteCertificate.GetExpirationDateString());
}
else
{
Console.WriteLine("Remote certificate is null.");
}
}
}