【C#】Socket中的ssl通信
引言
有个项目中用到了Socket ssl通信,在此记录一下.
证书
Socket ssl需要用到证书用来校验身份,而作为调试,我们只需用测试证书即可.
有个工具可以很方便地制作测试证书,下载地址为http://supersocket.codeplex.com/releases/view/59311
首先, 输入Common Name,密码和保存路径后,我们可以得到包含私钥的证书server.pfx.
然后,安装证书到电脑中,在IE选项中导出一份证书作为client.cer.
客户端
使用客户端的电脑需要安装client.cer到<受信任的根证书颁发机构>,且要把证书放在程序目录中,具体代码如下
class Program
{
private static SslStream _sslStream; static void Main(string[] args)
{ try
{
TcpClient client = new TcpClient("127.0.0.1", );
Console.WriteLine("Client connected.");
_sslStream = new SslStream(
client.GetStream(),
false,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
null
); X509CertificateCollection certs = new X509CertificateCollection();
X509Certificate cert = X509Certificate.CreateFromCertFile(System.Environment.CurrentDirectory + @"\" + "client.cer");
certs.Add(cert);
//验证证书
try
{
_sslStream.AuthenticateAsClient("test", certs, SslProtocols.Tls, false);
}
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();
Console.ReadLine();
return;
} //开始读取消息
Task.Factory.StartNew(() =>
{
ReadMessage(_sslStream);
}); Console.WriteLine("按Q退出程序");
string message = "";
message = Console.ReadLine() + "<EOF>";
while (message != "Q")
{
byte[] bytes = Encoding.UTF8.GetBytes(message);
_sslStream.Write(bytes);
_sslStream.Flush();
Console.WriteLine("send:" + message);
message = Console.ReadLine() + "<EOF>";
} client.Close();
}
catch (Exception ex)
{ Console.WriteLine(ex);
Console.ReadLine();
}
} public static void ReadMessage(SslStream sslStream)
{
byte[] buffer = new byte[];
StringBuilder messageData = new StringBuilder();
int bytes = -;
do
{
bytes = sslStream.Read(buffer, , buffer.Length);
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, , bytes)];
decoder.GetChars(buffer, , bytes, chars, );
messageData.Append(chars);
if (messageData.ToString().IndexOf("<EOF>", StringComparison.Ordinal) != -)
{
break;
}
} while (bytes != ); string message = messageData.ToString().Replace("<EOF>", "");
Console.WriteLine("recevied:" + message);
ReadMessage(sslStream);
} private 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;
}
}
服务端
服务端电脑要安装server.pfx证书,且要把证书放在程序目录中,具体代码如下
class Program
{
static void Main(string[] args)
{
TcpListener listener = new TcpListener(IPAddress.Any, );
listener.Start(); Console.WriteLine("Waiting for a client to connect...");
TcpClient client = listener.AcceptTcpClient(); _sslStream = new SslStream(client.GetStream(), true); try
{
serverCertificate = new X509Certificate(Environment.CurrentDirectory + @"\" + "server.pfx", "");
_sslStream.AuthenticateAsServer(serverCertificate, false, SslProtocols.Tls, true);
}
catch (Exception ex)
{
Console.WriteLine(ex);
Console.ReadLine();
return;
} while (true)
{
string receivedMessage = ReadMessage(_sslStream);
Console.WriteLine("received:" + receivedMessage);
byte[] message = Encoding.UTF8.GetBytes("Success.<EOF>");
_sslStream.Write(message);
_sslStream.Flush();
}
} static X509Certificate serverCertificate = null;
private static SslStream _sslStream; static string ReadMessage(SslStream sslStream)
{
byte[] buffer = new byte[];
StringBuilder messageData = new StringBuilder();
int bytes = -;
do
{
bytes = sslStream.Read(buffer, , buffer.Length);
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, , bytes)];
decoder.GetChars(buffer, , bytes, chars, );
messageData.Append(chars);
if (messageData.ToString().IndexOf("<EOF>") != -)
{
break;
}
} while (bytes != ); return messageData.ToString();
} static void ProcessClient(TcpClient client)
{ SslStream sslStream = new SslStream(
client.GetStream(), true); try
{
sslStream.AuthenticateAsServer(serverCertificate, true, SslProtocols.Tls, true); Console.WriteLine("Waiting for client message...");
string messageData = ReadMessage(sslStream);
Console.WriteLine("Received: {0}", messageData); byte[] message = Encoding.UTF8.GetBytes("已收到信息.<EOF>");
sslStream.Write(message);
sslStream.Flush();
}
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.");
sslStream.Close();
client.Close();
return;
}
finally
{
sslStream.Close();
client.Close();
}
} }
注意事项
1.服务端验证方法AuthenticateAsServer的参数clientCertificateRequired如果为true,那在客户端也要安装server.pfx.
2.客户端验证方法AuthenticateAsClient的参数targetHost对应证书中Common Name,也就是受颁发者.
参考资料
https://msdn.microsoft.com/zh-cn/library/system.net.security.sslstream(v=vs.110).aspx
【C#】Socket中的ssl通信的更多相关文章
- Tomcat6和Tomcat7配置SSL通信的比较
<Tomcat6和Tomcat7配置SSL通信的比较> 作者:chszs,转载需注明.博客主页: http://blog.csdn.net/chszs 在项目开发过程中,尝尝会遇到Tomc ...
- SSL、TLS协议格式、HTTPS通信过程、RDP SSL通信过程
相关学习资料 http://www.360doc.com/content/10/0602/08/1466362_30787868.shtml http://www.gxu.edu.cn/college ...
- SSL 通信原理及Tomcat SSL 配置
SSL 通信原理及Tomcat SSL 双向配置 目录1 参考资料 .................................................................. ...
- Java 下 SSL 通信原理及实例
有关SSL的原理和介绍在网上已经有不少,对于Java下使用keytool生成证书,配置SSL通信的教程也非常多.但如果我们不能够亲自动手做一个SSL Sever和SSL Client,可能就永远也不能 ...
- SSL 通信原理及Tomcat SSL 双向配置
SSL 通信原理及Tomcat SSL 双向配置 目录1 参考资料 .................................................................. ...
- SSL、TLS协议格式、HTTPS通信过程、RDP SSL通信过程(缺heartbeat)
SSL.TLS协议格式.HTTPS通信过程.RDP SSL通信过程 相关学习资料 http://www.360doc.com/content/10/0602/08/1466362_30787868 ...
- 转 关于Https协议中的ssl加密解密流程
关于Https协议中的ssl加密解密流程 2016年09月28日 09:51:15 阅读数:14809 转载自:http://www.cnblogs.com/P_Chou/archive/2010/1 ...
- 【转】证书的应用之一 —— TCP&SSL通信实例及协议分析(下)
原文链接 前面两部分分别讲解了如何在.net程序中使用SSL实现安全通信以及SSL的通信过程,并通过抓包工具具体分析了ssl的握手过程,本文通过一个demo来模拟ssl协议,在TCP之上实现自己的安全 ...
- C#的Socket实现UDP协议通信
今天稍花化了一点时间,利用C#的Socket验证了UDP的通信,为接下来特地利用UDP做个分布式的通信仿真系统打下基础.众所周知,UDP 就是用户数据报协议,在互联网参考模型的第四层——传输层.与TC ...
随机推荐
- 我的Android进阶之旅------>解决Jackson等第三方转换Json的开发包在开启混淆后转换的实体类数据都是null的bug
1.错误描述 今天测试人员提了一个bug,说使用我们的app出现了闪退的bug,后来通过debug断点调试,发现我们的app转换服务器发送过来的json数据后,都是为null.而之前已经提测快一个月的 ...
- 服务系统 server端
from django.shortcuts import render,HttpResponse import json # Create your views here. from reposito ...
- springMvc获取特殊值
1.获取数组
- Android学习八---OpenCV JAVA API
OpenCV java API的文档说明在OpenCV-2.4.10-android-sdk/sdk/java/javadoc/index.html的文件夹下. 想用java API的方式进行Open ...
- sqlite时间段查询
同样的SQL语句,查不出数据来 select * from table1 where t1>='2017-6-1' and t1<='2017-6-5' 改成 select * from ...
- mapreduce数据不平衡时的处理方法
用mr处理大数据经常遇到数据不平衡的情况,这里的数据不平衡指的是,数据中有少部分key集中了大量的数据,导致其它的reduce都运行完了,只剩几个reduce在跑.这种情况一般有如下三种解决方法(原理 ...
- maven项目打WAR包记录
打了个war包,各种不顺,也是以前没打过的原因,眼高手低了…… cmd 进入项目目录 打开 运行----cmd 进入命令窗口 键入 cd 回车 输入E\:mars\cdc 键入 mvn clean p ...
- knockout 学习使用笔记-----event绑定传参ko属性
在绑定event的时候,需要传入ViewModal 本身的属性值(其实没必要,js直接能获取到,此处为测试相关参数的传递),如果不加(),会将绑定的function传进event(至于为嘛传了个fun ...
- Oracle数据安全(五)审计
一.审计的概念 审计是监视和记录用户对数据库所进行操作,以供DBA进行统计和分析.利用审计可以完成下列任务 保证用户能够对自己在数据库中的活动负责. 禁止用户在数据库中从事于自己职责不相符的活动 调查 ...
- 【HTML5校企公益课】第四天
1.上午考试没去.. 2.下午跟不上.. 变色.html <!DOCTYPE html> <html> <head> <meta charset=" ...