zoukankan      html  css  js  c++  java
  • 使用SSL确保通信中的数据安全

    aaa

    bbb


    #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

  • 相关阅读:
    Wide & Deep Learning for Recommender Systems
    两个经典问题
    Vlog简介
    中文dumps显示
    用Python提取中文关键词
    【STL】算法 — partial_sort
    c字符串分割 strtok()
    JSP的声明(statement)
    layui之ajax巨坑
    jQuery 库中的 $() 是什么?(答案如下)
  • 原文地址:https://www.cnblogs.com/jx270/p/3619969.html
Copyright © 2011-2022 走看看