前面两部分分别讲解了如何在.net程序中使用SSL实现安全通信以及SSL的通信过程,并通过抓包工具具体分析了ssl的握手过程,本文通过一个demo来模拟ssl协议,在TCP之上实现自己的安全通信。

 

创建证书

为了实现安全的通信,必须使用证书对传输的数据进行加密,有两种方法可以得到证书,一是安装CA服务器,使用CA来发放证书,二是通过makecert.exe工具自己创建。

创建服务器证书:
cmd>makecert.exe -r -pe -n "CN=MySslServer" -sky Exchange -ss My
创建客户端证书
cmd>makecert.exe -r -pe -n "CN=MySslClient" -sky Exchange -ss My
关于makecert.exe的更多信息可以操作这里。

 

建立TCP连接

使用普通的Socket类来建立TCP连接即可。后续的握手,传输数据都是在TCP之上的,在这里,定义每条信息的第一个字节是类型,0x01是整数,0x02是session key,0x03是应用层数据,0x04是错误信息,未使用。

我们知道TCP通信是stream的,消息没有边界,有可能发送方发送的数据,在接收方两次才能接收完,或者发送方连续发送两次数据,接收方一次就全部接受,这就要求应用层自己对消息的边界进行区分,常用的有3种方法,一是固定长度,所有消息长度一样,不够就填充,显然不够实用而且浪费带宽;二是定义消息边界,每条消息以固定字节流结尾如<EOF>,如果传输的数据刚好含有这样的字节流,就必须进行转义;三是消息的起始处使用固定字节来描述本消息的长度。本文为方便起见,没有进行消息边界处理,每两次发送有个间隔。


交换证书

在TCP连接建立之后,开始进行握手过程,主要是交换证书,交换session key。

server与client各自将自己的证书发送给对方,证书被export成.cer格式,只含有public key。证书的作用一是交换session key,二是发送数据时签名。



1 
      
    byte 
    [] certBytes  
    = 
     so.localCert.Export(X509ContentType.Cert);
 
     2 
      
    byte 
    [] sentBytes  
    = 
     AddType(certBytes, type);
 
     3 
     so.workSocket.Send(sentBytes,  
    0 
    , sentBytes.Length, SocketFlags.None);
 
     4 
     Console.WriteLine( 
    " 
    Send>>>>>>>>>>>>>>>>>>>>> 
    " 
    );
 
     5 
     PrintCert(so.localCert);
 
     6 
    。。。。。。
 
     7 
      
    byte 
    [] data  
    = 
     RemoveType(so.buffer, read);
 
     8 
     so.remoteCert  
    = 
      
    new 
     X509Certificate2(data);
 
     9 
     Console.WriteLine( 
    " 
    Recv<<<<<<<<<<<<<<<<<<<<<< 
    " 
    );
 
    10 
     PrintCert(so.remoteCert);



交换session key

本demo使用DES对称算法来加密,必须在发送应用层数据之前交换算法的key,使用双方约定固定的IV。

其中一方生成随机的key,用对方的证书加密,调用RSA的Encrypt方法,会使用Public key,将加密后的数据发送给对方,由于只有对方才有证书的private key,所以也只有对方才能解密出key,第三方即使中途截获了数据也不能破解出key。




生成session key



1 
     RSACryptoServiceProvider rsa  
    = 
     (RSACryptoServiceProvider)so.remoteCert.PublicKey.Key;
 
    2 
      
    byte 
    [] encrypedSessionKey  
    = 
     rsa.Encrypt(so.localSessionKey,  
    false 
    );
 
    3 
      
    byte 
    [] sentBytes  
    = 
     AddType(encrypedSessionKey, type);
 
    4 
     so.workSocket.Send(sentBytes,  
    0 
    , sentBytes.Length, SocketFlags.None);
 
    5 
     Console.WriteLine( 
    " 
    Send>>>>>>>>>>>>>>>>>>>>> 
    " 
    );
 
    6 
     PrintSessionKey(so.localSessionKey);



 




sprint postgres 数据库连接数_网络

sprint postgres 数据库连接数_网络_02

解析session key


1       
    byte 
    [] data  
    = 
     RemoveType(so.buffer, read);
     2 
     RSACryptoServiceProvider rsa  
    = 
     (RSACryptoServiceProvider)so.localCert.PrivateKey;
     3 
     so.remoteSessionKey  
    = 
     rsa.Decrypt(data,  
    false 
    );
     4 
     Console.WriteLine( 
    " 
    Recv<<<<<<<<<<<<<<<<<<<<<< 
    " 
    );
     5 
     PrintSessionKey(so.remoteSessionKey);


发送加密和签名数据

发送数据使用DES算法加密,防止被第三方截获;同时对发送的数据签名,让对方确认数据没有被篡改并且确认数据是自己发送的。

数据格式:


0x03

密文长度

密文

签名长度

签名


对原文使用hash算法,并使用自己的证明对hash进行签名,签名是使用的private key,接收方收到数据后,用DES解密出原文,对原文计算hash,然后对收到的签名使用对方的证书的public key还原,比较与hash是否一致。


sprint postgres 数据库连接数_网络

sprint postgres 数据库连接数_网络_02

加密数据并签名

1        MemoryStream memoryStream        = 
        
      new 
       MemoryStream();
        2       
        3         
      // 
       encrypt 
      
        4         
       DESCryptoServiceProvider des  
      = 
        
      new 
       DESCryptoServiceProvider();
        5        ICryptoTransform cTransform  
      = 
       des.CreateEncryptor(so.remoteSessionKey,  
      new 
        
      byte 
      [ 
      8 
      ]);
        6        MemoryStream ms  
      = 
        
      new 
       MemoryStream();
        7        CryptoStream encStream  
      = 
        
      new 
       CryptoStream(ms, cTransform, CryptoStreamMode.Write);
        8        encStream.Write(so.sentData,  
      0 
      , so.sentData.Length);
        9        encStream.FlushFinalBlock();
       10       
       11         
      byte 
      [] temp  
      = 
       ms.ToArray();
       12        memoryStream.Write(BitConverter.GetBytes(temp.Length),  
      0 
      ,  
      4 
      );
       13        memoryStream.Write(temp,  
      0 
      , temp.Length);
       14       
       15         
      // 
       hash 
      
       16         
       MD5CryptoServiceProvider md5  
      = 
        
      new 
       MD5CryptoServiceProvider();
       17         
      byte 
      [] hash  
      = 
       md5.ComputeHash(so.sentData);
       18       
       19         
      // 
       sign 
      
       20         
       RSACryptoServiceProvider rsa  
      = 
       (RSACryptoServiceProvider) so.localCert.PrivateKey;
       21         
      byte 
      [] sign  
      = 
       rsa.SignHash(hash, CryptoConfig.MapNameToOID( 
      " 
      MD5 
      " 
      ));
       22       
       23        memoryStream.Write(BitConverter.GetBytes(sign.Length),  
      0 
      ,  
      4 
      );
       24        memoryStream.Write(sign,  
      0 
      , sign.Length);
       25       
       26         
      byte 
      [] sentBytes  
      = 
       AddType(memoryStream.ToArray(), type);
       27        so.workSocket.Send(sentBytes,  
      0 
      , sentBytes.Length, SocketFlags.None);
       28        Console.WriteLine( 
      " 
      Send>>>>>>>>>>>>>>>>>>>>> 
      " 
      );
       29        PrintData(so.sentData);



sprint postgres 数据库连接数_网络

sprint postgres 数据库连接数_网络_02

解密数据并验证

1               byte       [] data  
      = 
       RemoveType(so.buffer, read);
        2       
        3               // 
       Decrypt 
      
        4                DESCryptoServiceProvider des  
      = 
        
      new 
       DESCryptoServiceProvider();
        5        ICryptoTransform cTransform        = 
       des.CreateDecryptor(so.localSessionKey,  
      new 
        
      byte 
      [ 
      8 
      ]);
        6               int 
       len  
      = 
       BitConverter.ToInt32(data,  
      0 
      );
        7               byte 
      [] cipherText  
      = 
        
      new 
        
      byte 
      [len];
        8        Array.Copy(data,        4 
      , cipherText,  
      0 
      , len);
        9        MemoryStream ms2        = 
        
      new 
       MemoryStream(cipherText);
       10        CryptoStream decStream        = 
        
      new 
       CryptoStream(ms2, cTransform, CryptoStreamMode.Read);
       11       
       12        Byte[] tempBuffer        = 
        
      new 
       Byte[ 
      1024 
      ];
       13        Byte[] outputBytes        = 
        
      new 
        
      byte 
      [ 
      0 
      ];
       14               int 
       nRead  
      = 
       decStream.Read(tempBuffer,  
      0 
      , tempBuffer.Length);
       15               int 
       nLength  
      = 
        
      0 
      ;
       16               while 
       ( 
      0 
        
      != 
       nRead)
       17        {
       18        nLength        = 
       outputBytes.Length;
       19        Array.Resize(       ref 
       outputBytes, nLength  
      + 
       nRead);
       20        Array.Copy(tempBuffer,        0 
      , outputBytes, nLength, nRead);
       21        nRead        = 
       decStream.Read(tempBuffer,  
      0 
      , tempBuffer.Length);
       22        }
       23        so.recvData        = 
       outputBytes;
       24        Console.WriteLine(       " 
      Recv<<<<<<<<<<<<<<<<<<<<<< 
      " 
      );
       25        PrintData(so.recvData);
       26       
       27               // 
       hash 
      
       28                MD5CryptoServiceProvider md5  
      = 
        
      new 
       MD5CryptoServiceProvider();
       29               byte 
      [] hash  
      = 
       md5.ComputeHash(so.recvData);
       30       
       31               // 
       verify 
      
       32                 
      int 
       signlen  
      = 
       BitConverter.ToInt32(data, len  
      + 
        
      4 
      );
       33               byte 
      [] sign  
      = 
        
      new 
        
      byte 
      [signlen];
       34        Array.Copy(data,        4 
      + 
      len 
      + 
      4 
      ,sign,  
      0 
      , signlen);
       35        RSACryptoServiceProvider rsa        = 
       (RSACryptoServiceProvider)so.remoteCert.PublicKey.Key;
       36               try 
      
       37        {
       38               bool 
       verify  
      = 
       rsa.VerifyHash(hash, CryptoConfig.MapNameToOID( 
      " 
      MD5 
      " 
      ), sign);
       39               if 
       (verify)
       40        {
       41        Console.WriteLine(       " 
      verify correct! 
      " 
      );
       42        }
       43               else 
      
       44        {
       45        Console.WriteLine(       " 
      verify error! 
      " 
      );
       46        }
       47        }
       48               catch 
      
       49        {
       50        Console.WriteLine(       " 
      verify error! 
      " 
      );
       51               return 
       PackageType.Error;
       52        }


运行结果


sprint postgres 数据库连接数_网络

sprint postgres 数据库连接数_网络_02

服务器端输出

1      C:\D\BACKUP\Projects\TestProject\MySSLServer\bin\Debug      >      MySSLServer.exe
       2      Recv      <<<<<<<<<<<<<<<<<<<<<<      
       3             ============================================      
       4      cert
       5             ============================================      
       6      Subject: CN      =      MySslClient
       7      Issuer: CN      =      MySslClient
       8      Version:       3      
       9      Valid Date:       7      / 
     7 
     / 
     2010 
       
     11 
     : 
     25 
     : 
     28 
      AM
      10      Expiry Date:       1      / 
     1 
     / 
     2040 
       
     7 
     : 
     59 
     : 
     59 
      AM
      11      Thumbprint: D9AE7CF97A254FCA05EB7B704DDC90878FC56B0C
      12      Serial Number: 2500552056343D874C0B714A71CB047B
      13      Friendly Name: RSA
      14      Public Key Format:       30        
     81 
       
     89 
       
     02 
       
     81 
       
     81 
       
     00 
      9f 6f  
     17 
       
     84 
      0f  
     03 
      a0 8c b7  
     86 
       
     45 
       
     49 
      ba 0c c5 ab  
     37 
      c9  
     30 
       
     24 
       
     32 
      b5 dc  
     90 
       
     31 
      e4 d6
      15       ea       83        
     45 
      1f c8 2d dd 2f  
     81 
      3e da  
     09 
       
     44 
      7f 2a cf bb  
     18 
      9a  
     92 
       
     28 
      d3  
     79 
      f0  
     33 
      b8  
     04 
      f2 1a 1d f8 e0 b6 f9 cc da  
     36 
       
     16 
      2b e3
      16       8b 8d       82       5f 9c  
     88 
      6a  
     79 
       
     54 
       
     53 
      4f  
     08 
       
     10 
      dc b9  
     53 
      f1 c8 d4 bd 3d c4  
     94 
       
     71 
      1d db a2  
     76 
       
     65 
      8c  
     37 
      a3 cd  
     88 
      0d a0  
     72 
      0e  
     93 
      3a
      17             64        
     62 
      dc  
     90 
      cf  
     19 
      3f f7  
     58 
       
     59 
      d6 bd 4e 3f a4  
     15 
       
     30 
      5b  
     36 
       
     75 
      2f  
     02 
       
     03 
       
     01 
       
     00 
       
     01 
     
      18      Send      >>>>>>>>>>>>>>>>>>>>>      
      19             ============================================      
      20      cert
      21             ============================================      
      22      Subject: CN      =      MySslServer
      23      Issuer: CN      =      MySslServer
      24      Version:       3      
      25      Valid Date:       7      / 
     7 
     / 
     2010 
       
     11 
     : 
     25 
     : 
     32 
      AM
      26      Expiry Date:       1      / 
     1 
     / 
     2040 
       
     7 
     : 
     59 
     : 
     59 
      AM
      27      Thumbprint: 5B1CEC828E92A64950284E557477FDD7E2C05300
      28      Serial Number: 907E95210C949144FD68342B32FD07
      29      Friendly Name: RSA
      30      Public Key Format:       30        
     81 
       
     89 
       
     02 
       
     81 
       
     81 
       
     00 
      a4  
     97 
       
     38 
      0d dd c7 fa 6b b3 e6  
     23 
       
     17 
      df cd bf  
     06 
      c7  
     40 
      e1 5e 9a  
     04 
       
     81 
       
     02 
       
     62 
       
     00 
      b5
      31             52        
     82 
      c9 6d b0 fc  
     16 
      ce e8  
     72 
      be ae  
     31 
       
     80 
       
     85 
       
     44 
       
     75 
      6c 1d 6a 2c  
     33 
       
     55 
      ee  
     04 
      6a fd f8 f4 ff 3a e0  
     22 
       
     28 
      a7 4f f8 c4 ba  
     96 
     
      32       c7 e6 f0       27       aa  
     43 
       
     09 
       
     11 
      ce eb cb 5e fe  
     63 
       
     84 
      ef e0  
     74 
       
     11 
       
     99 
       
     91 
      5d a0  
     39 
      5b  
     54 
      e6  
     74 
      8d db c8 ce d2 bd  
     08 
       
     53 
       
     63 
       
     19 
      3d d6
      33       4c       37        
     99 
      b1  
     28 
      6a  
     07 
      2b 0c  
     70 
       
     49 
      fa df 9e ed 8b 2d e0 ed bf  
     03 
       
     02 
       
     03 
       
     01 
       
     00 
       
     01 
     
      34      Send      >>>>>>>>>>>>>>>>>>>>>      
      35             ============================================      
      36      session key
      37             ============================================      
      38      Session Key:       44        
     97 
      AC  
     07 
      5E  
     41 
       
     27 
      0B[ 
     8 
     ]
      39      Recv      <<<<<<<<<<<<<<<<<<<<<<      
      40             ============================================      
      41      session key
      42             ============================================      
      43      Session Key: BD       28        
     62 
       
     18 
       
     04 
       
     90 
      C9  
     57 
     [ 
     8 
     ]
      44      Recv      <<<<<<<<<<<<<<<<<<<<<<      
      45             ============================================      
      46      data
      47             ============================================      
      48      It      '      s just a text. 
     
      49             verify correct      ! 
     
      50      Send      >>>>>>>>>>>>>>>>>>>>>      
      51             ============================================      
      52      data
      53             ============================================      
      54      Response to client.

sprint postgres 数据库连接数_网络

sprint postgres 数据库连接数_网络_02

客户端输出

1      C:\D\BACKUP\Projects\TestProject\MySSLClient\bin\Debug      >      MySSLClient.exe       10.175      . 
     13.77 
     
       2      Send      >>>>>>>>>>>>>>>>>>>>>      
       3             ============================================      
       4      cert
       5             ============================================      
       6      Subject: CN      =      MySslClient
       7      Issuer: CN      =      MySslClient
       8      Version:       3      
       9      Valid Date:       7      /      7 
     / 
     2010 
       
     11 
     : 
     25 
     : 
     28 
      AM
      10      Expiry Date:       1      /      1 
     / 
     2040 
       
     7 
     : 
     59 
     : 
     59 
      AM
      11      Thumbprint: D9AE7CF97A254FCA05EB7B704DDC90878FC56B0C
      12      Serial Number: 2500552056343D874C0B714A71CB047B
      13      Friendly Name: RSA
      14      Public Key Format:       30             81 
       
     89 
       
     02 
       
     81 
       
     81 
       
     00 
      9f 6f  
     17 
       
     84 
      0f  
     03 
      a0 8c b7  
     86 
       
     45 
       
     49 
      ba 0c c5 ab  
     37 
      c9  
     30 
       
     24 
       
     32 
      b5 dc  
     90 
       
     31 
      e4 d6
      15       ea       83             45 
      1f c8 2d dd 2f  
     81 
      3e da  
     09 
       
     44 
      7f 2a cf bb  
     18 
      9a  
     92 
       
     28 
      d3  
     79 
      f0  
     33 
      b8  
     04 
      f2 1a 1d f8 e0 b6 f9 cc da  
     36 
       
     16 
      2b e3
      16       8b 8d       82       5f 9c       88 
      6a  
     79 
       
     54 
       
     53 
      4f  
     08 
       
     10 
      dc b9  
     53 
      f1 c8 d4 bd 3d c4  
     94 
       
     71 
      1d db a2  
     76 
       
     65 
      8c  
     37 
      a3 cd  
     88 
      0d a0  
     72 
      0e  
     93 
      3a
      17             64             62 
      dc  
     90 
      cf  
     19 
      3f f7  
     58 
       
     59 
      d6 bd 4e 3f a4  
     15 
       
     30 
      5b  
     36 
       
     75 
      2f  
     02 
       
     03 
       
     01 
       
     00 
       
     01 
     
      18      Recv      <<<<<<<<<<<<<<<<<<<<<<      
      19             ============================================      
      20      cert
      21             ============================================      
      22      Subject: CN      =      MySslServer
      23      Issuer: CN      =      MySslServer
      24      Version:       3      
      25      Valid Date:       7      /      7 
     / 
     2010 
       
     11 
     : 
     25 
     : 
     32 
      AM
      26      Expiry Date:       1      /      1 
     / 
     2040 
       
     7 
     : 
     59 
     : 
     59 
      AM
      27      Thumbprint: 5B1CEC828E92A64950284E557477FDD7E2C05300
      28      Serial Number: 907E95210C949144FD68342B32FD07
      29      Friendly Name: RSA
      30      Public Key Format:       30             81 
       
     89 
       
     02 
       
     81 
       
     81 
       
     00 
      a4  
     97 
       
     38 
      0d dd c7 fa 6b b3 e6  
     23 
       
     17 
      df cd bf  
     06 
      c7  
     40 
      e1 5e 9a  
     04 
       
     81 
       
     02 
       
     62 
       
     00 
      b5
      31             52             82 
      c9 6d b0 fc  
     16 
      ce e8  
     72 
      be ae  
     31 
       
     80 
       
     85 
       
     44 
       
     75 
      6c 1d 6a 2c  
     33 
       
     55 
      ee  
     04 
      6a fd f8 f4 ff 3a e0  
     22 
       
     28 
      a7 4f f8 c4 ba  
     96 
     
      32       c7 e6 f0       27       aa       43 
       
     09 
       
     11 
      ce eb cb 5e fe  
     63 
       
     84 
      ef e0  
     74 
       
     11 
       
     99 
       
     91 
      5d a0  
     39 
      5b  
     54 
      e6  
     74 
      8d db c8 ce d2 bd  
     08 
       
     53 
       
     63 
       
     19 
      3d d6
      33       4c       37             99 
      b1  
     28 
      6a  
     07 
      2b 0c  
     70 
       
     49 
      fa df 9e ed 8b 2d e0 ed bf  
     03 
       
     02 
       
     03 
       
     01 
       
     00 
       
     01 
     
      34      Send      >>>>>>>>>>>>>>>>>>>>>      
      35             ============================================      
      36      session key
      37             ============================================      
      38      Session Key: BD       28             62 
       
     18 
       
     04 
       
     90 
      C9  
     57 
     [ 
     8 
     ]
      39      Recv      <<<<<<<<<<<<<<<<<<<<<<      
      40             ============================================      
      41      session key
      42             ============================================      
      43      Session Key:       44             97 
      AC  
     07 
      5E  
     41 
       
     27 
      0B[ 
     8 
     ]
      44      Send      >>>>>>>>>>>>>>>>>>>>>      
      45             ============================================      
      46      data
      47             ============================================      
      48      It      '      s just a text.      
      49             Recv      <<<<<<<<<<<<<<<<<<<<<<      
      50             ============================================      
      51      data
      52             ============================================      
      53      Response to client.
      54      verify correct      !

下载代码