#region Server
/// <summary>
/// 用于保存非对称加密(数字证书)的公钥
/// </summary>
private string publicKey = string.Empty;
/// <summary>
/// 用于保存非对称加密(数字证书)的私钥
/// </summary>
private string pfxKey = string.Empty;

///===========================
///服务端代码
///===========================

/// <summary>
/// 用于跟客户端通信的Socket
/// </summary>
private Socket serverCommunicateSocket;
/// <summary>
/// 定义接收缓存块的大小
/// </summary>
private static int serverBufferSize = 1024;
/// <summary>
/// 缓存块
/// </summary>
byte[] bytesReceivedFromClient = new byte[serverBufferSize];
/// <summary>
/// 密钥K
/// </summary>
private string key = string.Empty;
StringBuilder messageFromClient = new StringBuilder();

/// <summary>
/// 开启服务器
/// </summary>
private void btnStartServer_Click(object sender, EventArgs e)
{
//先生成数字证书(模拟,及非对称密钥对)
RSAKeyInit();
//负责侦听
StartListen();
}

void RSAKeyInit()
{
RSAProcessor.CreateRSAKey(ref publicKey, ref pfxKey);

//本例中,先指定一对公钥、私钥
publicKey = "<RSAKeyValue><Modulus>httkQLJ52ODWcIoDont7izs0Kn8OIr3IJ+Q5DC3RgzojjphvHN/5N4miVN+U0fz405o53CRP0PUghyq0rbHZNj7ZW1M1Vh/ne4lDvP/q44QerhYewTUwT92tHj8GyYxvegkp98vT95YkjFJRByQCXrhKBW64ziqnDL2n9LeUPBM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
pfxKey = "<RSAKeyValue><Modulus>httkQLJ52ODWcIoDont7izs0Kn8OIr3IJ+Q5DC3RgzojjphvHN/5N4miVN+U0fz405o53CRP0PUghyq0rbHZNj7ZW1M1Vh/ne4lDvP/q44QerhYewTUwT92tHj8GyYxvegkp98vT95YkjFJRByQCXrhKBW64ziqnDL2n9LeUPBM=</Modulus><Exponent>AQAB</Exponent><P>vZPGLPJBxtjhoSSt7OXvAqalRU8IXmPbojk7/j9f1DW1DRCLwof6MjJqt4uAY9D/L/GPJh9zIddeVM3lkr9s6Q==</P><Q>tht1LlLi7XQJHsVfgJ1ewBjjOOzQSfmO+RTClWXKquuup4pblF51jSDK+5VlyibD5chzeO1mxjvzkEfcJNgTmw==</Q><DP>kZXfdfrhKqy5sX+ylaAKydViTHSiL6KuM8mSWfEfTZ+lF5BiVBUKvevb6nKWOZFxt8bhMNysFQwI5EVujSC2qQ==</DP><DQ>hEsqM77vMEWNopcMLCkm/jKWT3JqVnM/lF+qhFHwi36v4PK4WO7OQvpBu8bqrZK/2ZxnlsAQW46OAJDTsshuZQ==</DQ><InverseQ>BfZy74k5EqN6l7faYHSYvqWuRMSWwp4dCXF43uT8wcf3kciYxIkbaNNY56ulJbCAN2SyDQkD3PF+Sp3qtJZ/Vg==</InverseQ><D>ADbI6fFekCGLNZKCfveDMq1dX9PjydpTPvz1ujc4ZeTpuYg0ZO9WDeiCAXB5Y/vqySstfFPybHp3Gr/OmZf2qEbKQlK6Ztms3R30rnqk/2/XHtAm5AeVLhf03q/+76mtvgtUTspgth55JpIKGYNKcQTJBbgepbyVT26YjMwrMoE=</D></RSAKeyValue>";
}

void StartListen()
{
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("192.168.1.103"), 8009);
//负责侦听的socket
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(iep);
listenSocket.Listen(50);
listenSocket.BeginAccept(new AsyncCallback(this.Accepted), listenSocket);
ListBoxShow("开始侦听...");
btnStartServer.Enabled = false;
}

/// <summary>
/// 负责客户端的连接,并开始将自己置于接收状态
/// </summary>
void Accepted(IAsyncResult result)
{
Socket listenSocket = result.AsyncState as Socket;

//初始化和客户端进行通信的socket
serverCommunicateSocket = listenSocket.EndAccept(result);
ListBoxShow("有客户端连接到...");
serverCommunicateSocket.BeginReceive(bytesReceivedFromClient, 0, serverBufferSize, SocketFlags.None,
new AsyncCallback(this.ReceivedFromClient), null);
}

/// <summary>
/// 负责处理接收自客户端的数据
/// </summary>
void ReceivedFromClient(IAsyncResult result)
{
int read = serverCommunicateSocket.EndReceive(result);
if (read > 0)
{
messageFromClient.Append(UTF32Encoding.Default.GetString(bytesReceivedFromClient, 0, read));
//处理并显示数据
ProcessAndShowInServer();
serverCommunicateSocket.BeginReceive(bytesReceivedFromClient, 0, serverBufferSize, 0,
new AsyncCallback(ReceivedFromClient), null);
}
}

private void ProcessAndShowInServer()
{
string msg = messageFromClient.ToString();
//如果接收到<EOF>表示完成一次,否则继续将自己置于接收状态
if (msg.IndexOf("<EOF>") > -1)
{
//如果客户端发送Key,则负责初始化Key
if (msg.IndexOf("<KEY>") > -1)
{
//用私钥解密发送过来的Key信息
key = RSAProcessor.RSADecrypt(pfxKey, msg.Substring(0, msg.Length - 10));
ListBoxShow(string.Format("接收到客户端密钥:{0}", key));
}
else
{
//解密SSL通道中发送过来的密文并显示
ListBoxShow(string.Format("接收到客户端消息:{0}", RijndaelProcessor.DecryptString(msg.Substring(0, msg.Length - 5), key)));
}
}
messageFromClient.Clear();
}

/// <summary>
/// 负责向客户端发送数据
/// </summary>
private void btnStartSendToClient_Click(object sender, EventArgs e)
{
//加密消息体
string msg = string.Format("{0}{1}", RijndaelProcessor.EncryptString(DateTime.Now.ToString(), key), "<EOF>");
RijndaelProcessor.DecryptString(msg.Substring(0, msg.Length - 5), key);
byte[] msgBytes = UTF32Encoding.Default.GetBytes(msg);
serverCommunicateSocket.BeginSend(msgBytes, 0, msgBytes.Length, SocketFlags.None, null, null);
ListBoxShow(string.Format("发送:{0}", msg));
}

/// <summary>
/// 界面显示
/// </summary>
private void ListBoxShow(string argMsg)
{
listBoxServer.BeginInvoke(new Action(() =>
{
listBoxServer.Items.Add(argMsg);
}));
}
#endregion


#region Client

/// <summary>
/// 用于保存非对称加密(数字证书)的公钥
/// </summary>
private string publicKey = "<RSAKeyValue><Modulus>httkQLJ52ODWcIoDont7izs0Kn8OIr3IJ+Q5DC3RgzojjphvHN/5N4miVN+U0fz405o53CRP0PUghyq0rbHZNj7ZW1M1Vh/ne4lDvP/q44QerhYewTUwT92tHj8GyYxvegkp98vT95YkjFJRByQCXrhKBW64ziqnDL2n9LeUPBM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

///==============================
/// 客户端代码
///==============================

///用于跟踪服务器通信的socket
private Socket clientCommunicateSocket;
/// <summary>
/// 用于暂存接收到的字符串
/// </summary>
StringBuilder messageFromServer = new StringBuilder();
/// <summary>
/// 定义接收存储块的大小
/// </summary>
private static int clientBufferSize = 1024;
/// <summary>
/// 缓存块
/// </summary>
byte[] bytesReceivedFromServer = new byte[clientBufferSize];

/// <summary>
/// 随机生产的key,在这里硬编码为"key123"
/// </summary>
private string keyCreateRandom = "key123";
//Guid.NewGuid().ToString().ToUpper().Replace("-", "") +Guid.NewGuid().ToString().ToUpper().Replace("-", "");

private void btnConnectToServer_Click(object sender, EventArgs e)
{
IPEndPoint iep = new IPEndPoint(IPAddress.Parse("192.168.1.103"), 8009);
Socket connectSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
connectSocket.BeginConnect(iep, new AsyncCallback(this.Connected), connectSocket);
btnConnectToServer.Enabled = false;
}

void Connected(IAsyncResult result)
{
clientCommunicateSocket = result.AsyncState as Socket;
clientCommunicateSocket.EndConnect(result);
clientCommunicateSocket.BeginReceive(bytesReceivedFromServer, 0, clientBufferSize, SocketFlags.None,
new AsyncCallback(this.ReceivedFromServer), null);
ListBoxClientShow("客户端连接上服务器...");
//连接成功便发送密钥K给服务器
SendKey();
}

void ReceivedFromServer(IAsyncResult result)
{
int read = clientCommunicateSocket.EndReceive(result);
if (read > 0)
{
messageFromServer.Append(UTF32Encoding.Default.GetString(bytesReceivedFromServer, 0, read));
//处理并显示客户端数据
ProcessAndShowInClient();
clientCommunicateSocket.BeginReceive(bytesReceivedFromServer, 0, clientBufferSize, 0,
new AsyncCallback(ReceivedFromServer), null);
}
}

void ProcessAndShowInClient()
{
//如果接收到<EOF>表示完成一次接收,否则继续将自己置于接收状态
if (messageFromServer.ToString().IndexOf("<EOF>") > -1)
{
//解密消息体并呈现出来
ListBoxClientShow(string.Format("接收到服务器消息:{0}",
RijndaelProcessor.DecryptString(
messageFromServer.ToString().Substring(0, messageFromServer.ToString().Length - 5)
, keyCreateRandom)));
messageFromServer.Clear();
}
}

private void btnStartSendToServer_Click(object sender, EventArgs e)
{
//加密消息体
string msg = string.Format("{0}{1}",
RijndaelProcessor.EncryptString(DateTime.Now.ToString(), keyCreateRandom), "<EOF>");
byte[] msgBytes = UTF32Encoding.Default.GetBytes(msg);
clientCommunicateSocket.BeginSend(msgBytes, 0, msgBytes.Length, SocketFlags.None, null, null);
ListBoxClientShow(string.Format("发送:{0}", msg));
}

void SendKey()
{
string msg = RSAProcessor.RSAEncrypt(publicKey, keyCreateRandom) + "<KEY><EOF>";
byte[] msgBytes = UTF32Encoding.Default.GetBytes(msg);
clientCommunicateSocket.BeginSend(msgBytes, 0, msgBytes.Length, SocketFlags.None, null, null);
ListBoxClientShow(string.Format("发送:{0}", keyCreateRandom));
}

void ListBoxClientShow(string argMsg)
{
listBoxClient.BeginInvoke(new Action(() =>
{
listBoxClient.Items.Add(argMsg);
}));
}

#endregion

using System; 
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace LibAlgorithm
{
/// <summary>
/// Rijndael对称加密算法
/// </summary>
public class RijndaelProcessor
{
/// <summary>
/// 缓冲区大小
/// </summary>
private static int bufferSize = 128 * 1024;

/// <summary>
/// 密钥salt
/// </summary>
private static byte[] salt = { 134, 216, 7, 36, 88, 164, 91, 227, 174, 76, 191, 197, 192, 154, 200, 248 };
//salt用来防止穷举暴力破解(salt是在密钥导出之前在密码末尾引入的随机字节,它使得这类攻击变得非常困难)

/// <summary>
/// 初始化向量
/// </summary>
private static byte[] iv = { 134, 216, 7, 36, 88, 164, 91, 227, 174, 76, 191, 197, 192, 154, 200, 248 };
//初始化向量iv起到的也是增强破解难度的作用

/// <summary>
/// 初始化 并返回对称加密算法
/// </summary>
/// <param name="argKey"></param>
/// <param name="argSalt"></param>
/// <returns></returns>
private static SymmetricAlgorithm CreateRijindael(string argKey, byte[] argSalt)
{
PasswordDeriveBytes pdb = new PasswordDeriveBytes(argKey, argSalt, "SHA256", 1000);
SymmetricAlgorithm sma = Rijndael.Create();
sma.KeySize = 256;
sma.Key = pdb.GetBytes(32);
sma.Padding = PaddingMode.PKCS7;
return sma;
}

public static string EncryptString(string argInput, string argKey)
{
using (MemoryStream memoryStream = new MemoryStream())
using (SymmetricAlgorithm algorithm = CreateRijindael(argKey, salt))
{
algorithm.IV = iv;
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, algorithm.CreateEncryptor(),
CryptoStreamMode.Write))
{
byte[] bytes = UTF32Encoding.Default.GetBytes(argInput);
cryptoStream.Write(bytes, 0, bytes.Length);
cryptoStream.Flush();
}
return Convert.ToBase64String(memoryStream.ToArray());
}
}

public static string DecryptString(string argInput, string argKey)
{
using (MemoryStream inputMemoryStream = new MemoryStream(Convert.FromBase64String(argInput)))
using (SymmetricAlgorithm algorithm = CreateRijindael(argKey, salt))
{
algorithm.IV = iv;
using (CryptoStream cryptoStream = new CryptoStream(inputMemoryStream, algorithm.CreateDecryptor(),
CryptoStreamMode.Read))
{
StreamReader sr = new StreamReader(cryptoStream);
return sr.ReadToEnd();
}
}
}

}
}

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;

namespace LibAlgorithm
{
/// <summary>
/// RSA非对称加密
/// </summary>
public class RSAProcessor
{
public static void CreateRSAKey(ref string publicKey, ref string pfxKey)
{
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
pfxKey = provider.ToXmlString(true);
publicKey = provider.ToXmlString(false);
}

public static string RSAEncrypt(string argXmlPublicKey, string argEncryptString)
{
byte[] btEncryptedSecret = Encoding.UTF8.GetBytes(argEncryptString);
btEncryptedSecret = CRSAWrap.EncryptBuffer(argXmlPublicKey, btEncryptedSecret);
return Convert.ToBase64String(btEncryptedSecret);
}

public static string RSADecrypt(string xmlPrivateKey, string argDecryptString)
{
byte[] btDecryptedSecred = Convert.FromBase64String(argDecryptString);
btDecryptedSecred = CRSAWrap.DecryptBuffer(xmlPrivateKey,btDecryptedSecred);
return Encoding.UTF8.GetString(btDecryptedSecred);
}
}

class CRSAWrap
{
public static byte[] EncryptBuffer(string rsaKeyString, byte[] btSecret)
{
int keySize = 0;
int blockSize = 0;
int counter = 0;
int iterations = 0;
int index = 0;
byte[] btPlaintextToken;
byte[] btEncryptedToken;
byte[] btEncryptedSecret;
RSACryptoServiceProvider rsaSender = new RSACryptoServiceProvider();
rsaSender.FromXmlString(rsaKeyString);
keySize = rsaSender.KeySize / 8;
blockSize = keySize - 11;

if ((btSecret.Length % blockSize) != 0)
{
iterations = btSecret.Length / blockSize + 1;
}
else
{
iterations = btSecret.Length / blockSize;
}
btPlaintextToken = new byte[blockSize];
btEncryptedSecret = new byte[iterations * keySize];
for (index = 0, counter = 0; counter < iterations; counter++,index += blockSize)
{
if (counter == (iterations - 1))
{
int lastblockSize = btSecret.Length % blockSize;
btPlaintextToken = new byte[lastblockSize];
Array.Copy(btSecret, index, btPlaintextToken, 0, lastblockSize);
}
else
{
Array.Copy(btSecret, index, btPlaintextToken, 0, blockSize);
}
btEncryptedToken = rsaSender.Encrypt(btPlaintextToken, false);
Array.Copy(btEncryptedToken, 0, btEncryptedSecret, counter * keySize, keySize);
}
return btEncryptedSecret;
}

public static byte[] DecryptBuffer(string argRsaKeyString, byte[] btEncryptedSecret)
{
int keySize = 0;
int blockSize = 0;
int counter = 0;
int iterations = 0;
int index = 0;
int byteCount = 0;
byte[] btPlaintextToken;
byte[] btEncryptedToken;
byte[] btDecryptedSecret;
RSACryptoServiceProvider rsaReceiver=new RSACryptoServiceProvider();
rsaReceiver.FromXmlString(argRsaKeyString);
keySize = rsaReceiver.KeySize/8;
blockSize = keySize - 11;
if ((btEncryptedSecret.Length%keySize) != 0)
{
return null;
}
iterations = btEncryptedSecret.Length/keySize;
btEncryptedToken=new byte[keySize];
Queue<byte[]> tokenQueue=new Queue<byte[]>();
for (index = 0,counter = 0; counter < iterations; index += blockSize,counter++)
{
Array.Copy(btEncryptedSecret,counter*keySize,btEncryptedToken,0,keySize);
btPlaintextToken = rsaReceiver.Decrypt(btEncryptedToken, false);
tokenQueue.Enqueue(btPlaintextToken);
}
byteCount = 0;
foreach (var plainTextToken in tokenQueue)
{
byteCount += plainTextToken.Length;
}
counter = 0;
btDecryptedSecret=new byte[byteCount];
foreach (var plainTextToken in tokenQueue)
{
if (counter==(iterations-1))
{
Array.Copy(plainTextToken,0,btDecryptedSecret,btDecryptedSecret.Length-plainTextToken.Length,plainTextToken.Length);
}
else
{
Array.Copy(plainTextToken,0,btDecryptedSecret,counter*blockSize,blockSize);
}
counter++;
}
return btDecryptedSecret;
}
}
}

源码下载地址:Test117_使用SSL确保通信中的数据安全.rar

使用SSL确保通信中的数据安全的更多相关文章

  1. 编写高质量代码改善C#程序的157个建议——建议117:使用SSL确保通信中的数据安全

    建议117:使用SSL确保通信中的数据安全 SSL(Secure Socket Layer)最初是由NetScape公司设计的,用于Web安全的网络协议.目前它已经广泛应用到各类网络传输通信中了.SS ...

  2. [转]如何借助 TLS/SSL 确保套接字连接的安全(使用 C#/VB/C++ 和 XAML 的 Windows 应用商店应用)

    本文转自:http://msdn.microsoft.com/zh-cn/library/windows/apps/jj150597.aspx 本主题将展示在使用 StreamSocket 功能时,如 ...

  3. Filebeat与Logstash配置SSL加密通信

    为了保证应用日志数据的传输安全,我们可以使用SSL相互身份验证来保护Filebeat和Logstash之间的连接. 这可以确保Filebeat仅将加密数据发送到受信任的Logstash服务器,并确保L ...

  4. Security基础(三):OpenSSL及证书服务、邮件TLS/SSL加密通信

    一.OpenSSL及证书服务 目标: 本案例要求熟悉OpenSSL工具的基本使用,完成以下任务操作: 使用OpenSSL加密/解密文件 搭建企业自有的CA服务器,为颁发数字证书提供基础环境 方案: 使 ...

  5. 如何让你的传输更安全——NIO模式和BIO模式实现SSL协议通信

    对于SSL/TLS协议,如果要每个开发者都自己去实现显然会带来不必要的麻烦,正是为了解决这个问题Java为广大开发者提供了Java安全套接字扩展--JSSE,它包含了实现Internet安全通信的一系 ...

  6. 语音通信中终端上的时延(latency)及减小方法

    时延是语音通信中的一个重要指标,当端到端(end2end)的时延(即one-way-delay,单向时延)低于150Ms时人感觉不到,当端到端的时延超过150Ms且小于450Ms时人能感受到但能忍受不 ...

  7. SSL握手通信详解及linux下c/c++ SSL Socket代码举例

    SSL握手通信详解及linux下c/c++ SSL Socket代码举例 摘自:http://www.169it.com/article/3215130236.html   分享到:8     发布时 ...

  8. SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码)

    SSL握手通信详解及linux下c/c++ SSL Socket代码举例(另附SSL双向认证客户端代码) 摘自: https://blog.csdn.net/sjin_1314/article/det ...

  9. 【DSP开发】硬件信号量在多核处理器核间通信中的应用

    硬件信号量在多核处理器核间通信中的应用 刘德保1,汪安民1,韩道文2 1.同方电子科技有限公司研究所,九江 332009:2.解放军电子工程学院 摘要: 在多核处理器的软件设计中,核间通信机制是关键所 ...

随机推荐

  1. pycharm 格式化代码

    有时候将空格键和tab键混用,在windows上没什么事情,但是如果移动到linux就会有问题,所以我们在移动到linux上之前要先格式化一下代码: ctrl+alt+L可以格式化,但是和锁屏快捷键冲 ...

  2. 错误代码2104:无法下载Silverlight应用程序。请查看Web服务器设置

    今天调试Silverlight程序,把ClientBin文件夹下的.xap文件删除后遇到这样一个问题:错误代码2104:无法下载Silverlight应用程序.请查看Web服务器设置.在网上查了一下, ...

  3. Idea KeyGen

    import java.math.BigInteger; import java.util.Date; import java.util.Random; import java.util.Scanne ...

  4. Opensturt和Struct区别

    1 OpenStruct和Struct区别,Opestruct你需要创建时,直接给属性赋值,而Struct需要先定义属性后 ,再给属性赋值.选择哪个就看你对属性赋值的时机, 2 Struct和Open ...

  5. java GUI之基本图形

    1.为了支持图形用户界面程序设计,java1.0的标准类库中包含一个抽象窗口工具箱(Abstract Window Toolkit,AWT). 这个工具箱极不成熟,其编程模型也不是面向对象的,有很大的 ...

  6. delphi 程序全屏显示无标题栏,覆盖整个屏幕

    delphi 程序全屏显示无标题栏,覆盖整个屏幕,这个在做工控机或屏保时有用的,所以记下 procedure TMainFrm.FormCreate(Sender: TObject); begin w ...

  7. 把exe嵌入到自己的exe中。delphi xe3

    下面是一个把exe程序嵌入到我们自己的exe中.开发环境 Delphi XE3 Version 17.0.4625.53395.OS环境WIN7 SP1,由于xe3版本的引用库发生变化.换成其他版本的 ...

  8. 无法重新组织表 "ty_wf_ex_local_process_info" 的索引 "idx_prc_act_id" (分区 1),因为已禁用页级锁定。

    无法重新组织表 "ty_wf_ex_local_process_info" 的索引 "idx_prc_act_id" (分区 1),因为已禁用页级锁定. ALT ...

  9. Codeforces 418d Big Problems for Organizers [树形dp][倍增lca]

    题意: 给你一棵有n个节点的树,树的边权都是1. 有m次询问,每次询问输出树上所有节点离其较近结点距离的最大值. 思路: 1.首先是按照常规树形dp的思路维护一个子树节点中距离该点的最大值son_di ...

  10. OC基础(6)

    getter/setter方法 点语法 Self关键字 Super关键字 *:first-child { margin-top: 0 !important; } body > *:last-ch ...