![aaa aaa](//images0.cnblogs.com/blog/117155/201403/262118573581329.jpg) ![bbb bbb](//images0.cnblogs.com/blog/117155/201403/262118582495657.jpg) #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
|