Skip to content

Commit 1e043d4

Browse files
author
zhengshuxin
committed
Site updated: 2024-09-26 09:16:39
1 parent 130bf1a commit 1e043d4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+1555
-257
lines changed

2024/06/02/ssl_sni/index.html

+13-6
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<meta property="og:description" content="使用 SSL SNI 拦截 SSL 握手攻击一、概述SSL&#x2F;TLS是用于在网络上进行安全通信的加密协议,各网络公司为保证数据传输的安全性均采用了SSL&#x2F;TLS通信方式,相校于明文传输方式,SSL&#x2F;TLS对于计算成本要求更高,尤其是在SSL&#x2F;TLS握手阶段更是耗费了大量计算资源,攻击者可以轻易利用这一问题对服务端发起SSL&#x2F;TLS握手攻击,攻击者只需">
2525
<meta property="og:locale" content="zh_CN">
2626
<meta property="article:published_time" content="2024-06-02T13:34:00.000Z">
27-
<meta property="article:modified_time" content="2024-06-03T05:09:25.756Z">
27+
<meta property="article:modified_time" content="2024-09-26T01:15:07.265Z">
2828
<meta property="article:author" content="zsxxsz">
2929
<meta property="article:tag" content="SSL编程">
3030
<meta name="twitter:card" content="summary_large_image">
@@ -237,7 +237,7 @@
237237
<span class="post-meta mr-2">
238238
<i class="iconfont icon-chart"></i>
239239

240-
3.5k
240+
3.6k
241241

242242
</span>
243243

@@ -248,7 +248,7 @@
248248

249249

250250

251-
30 分钟
251+
31 分钟
252252

253253
</span>
254254

@@ -323,8 +323,8 @@ <h3 id="3-1、SSL-服务端"><a href="#3-1、SSL-服务端" class="headerlink" t
323323
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><code class="hljs c++"><span class="hljs-keyword">class</span> <span class="hljs-title class_">my_sni_checker</span> : <span class="hljs-keyword">public</span> acl::ssl_sni_checker &#123;<br><span class="hljs-keyword">public</span>:<br> <span class="hljs-built_in">my_sni_checker</span>() &#123;&#125;<br> ~<span class="hljs-built_in">my_sni_checker</span>() &#123;&#125;<br><br> <span class="hljs-comment">// @override</span><br> <span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">check</span><span class="hljs-params">(acl::sslbase_io* io, <span class="hljs-type">const</span> <span class="hljs-type">char</span>* sni, acl::string&amp; host)</span> </span>&#123;<br> <span class="hljs-keyword">if</span> (sni == <span class="hljs-literal">NULL</span> || *sni == <span class="hljs-number">0</span>) &#123;<br> <span class="hljs-comment">// 如果客户端未提供 SNI 标识字符串则返回错误,禁止进行 SSL 握手. </span><br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;No SNI=%p\r\n&quot;</span>, sni);<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> &#125;<br><br> <span class="hljs-comment">// 从 SNI 中提取服务端主机域名,并保存,以便 Acl SSL 模块选择本地的 SSL 证书</span><br> <span class="hljs-comment">// 并进行 SSL 握手。</span><br> <span class="hljs-function">acl::string <span class="hljs-title">buf</span><span class="hljs-params">(sni)</span></span>;<br> <span class="hljs-type">const</span> std::vector&lt;acl::string&gt;&amp; tokens = buf.<span class="hljs-built_in">split2</span>(<span class="hljs-string">&quot;|&quot;</span>);<br> <span class="hljs-keyword">if</span> (tokens.<span class="hljs-built_in">size</span>() != <span class="hljs-number">2</span>) &#123;<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;Invalid sni=%s\r\n&quot;</span>, sni);<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> &#125;<br><br> host = tokens[<span class="hljs-number">1</span>];<br><br> <span class="hljs-comment">// check_token(tokens[0]); // 应用自行检查加密串的合法性。</span><br><br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">&quot;Check sni ok, sni=%s, host=%s\r\n&quot;</span>, sni,, host.<span class="hljs-built_in">c_str</span>());<br><br> <span class="hljs-comment">// 返回 true 则允许 Acl SSL 模块可以进一步进行 SSL 握手。</span><br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br> &#125;<br>&#125;;<br></code></pre></td></tr></table></figure>
324324

325325
<p>SSL 客户端模块与服务端可以协商一个 sni 的生成规则,比如 sni 字符串类似于 <code>token|host</code>(比如:xxxxxx|myhost.test.com),期中 token 字段可以是双方私密生成的加密字符串,host 为主机域名。服务端仅针放行符合加密规则的客户端 SSL 连接,其它连接一概拦截。</p>
326-
<h4 id="3-1-2、创建僵尸-SSL-对象中添加-SNI-验证对象"><a href="#3-1-2、创建僵尸-SSL-对象中添加-SNI-验证对象" class="headerlink" title="3.1.2、创建僵尸 SSL 对象中添加 SNI 验证对象"></a>3.1.2、创建僵尸 SSL 对象中添加 SNI 验证对象</h4><p>下面代码是创建全局的 SSL 配置管理对象代码:</p>
327-
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c++">acl::sslbase_conf* ssl_conf = <span class="hljs-keyword">new</span> acl::<span class="hljs-built_in">openssl_conf</span>(<span class="hljs-literal">true</span>);<br></code></pre></td></tr></table></figure>
326+
<h4 id="3-1-2、创建全局-SSL-配置对象并绑定-SNI-验证对象"><a href="#3-1-2、创建全局-SSL-配置对象并绑定-SNI-验证对象" class="headerlink" title="3.1.2、创建全局 SSL 配置对象并绑定 SNI 验证对象"></a>3.1.2、创建全局 SSL 配置对象并绑定 SNI 验证对象</h4><p>下面代码是创建全局的 SSL 配置管理对象代码:</p>
327+
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs c++">acl::sslbase_conf* ssl_conf = <span class="hljs-keyword">new</span> acl::<span class="hljs-built_in">openssl_conf</span>(<span class="hljs-literal">true</span>);<br><span class="hljs-comment">// 添加服务端 SSL 证书</span><br></code></pre></td></tr></table></figure>
328328

329329
<p>全局 SSL 配置管理对象创建后,添加 SSL SNI 验证对象:</p>
330330
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs c++">ssl_conf-&gt;<span class="hljs-built_in">set_sni_checker</span>(<span class="hljs-keyword">new</span> <span class="hljs-built_in">ssl_sni_checker</span>());<br></code></pre></td></tr></table></figure>
@@ -333,13 +333,14 @@ <h4 id="3-1-3、与-SSL-客户端进行-SSL-握手"><a href="#3-1-3、与-SSL-
333333
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><code class="hljs c++"><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">ssl_handshake</span><span class="hljs-params">(acl::sslbase_conf&amp; ssl_conf, acl::socket_stream&amp; conn)</span> </span>&#123;<br> acl::sslbase_io* ssl = ssl_conf.<span class="hljs-built_in">create</span>(<span class="hljs-literal">false</span>);<br> <span class="hljs-keyword">if</span> (conn.<span class="hljs-built_in">setup_hook</span>(ssl) == ssl) &#123; <span class="hljs-comment">// SSL 握手失败,包括 SSL SNI 查检失败。</span><br> ssl-&gt;<span class="hljs-built_in">destroy</span>();<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> &#125;<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>&#125;<br></code></pre></td></tr></table></figure>
334334

335335
<h3 id="3-2、SSL-客户端"><a href="#3-2、SSL-客户端" class="headerlink" title="3.2、SSL 客户端"></a>3.2、SSL 客户端</h3><p>客户端在与服务端建立 TCP 连接后,进行 SSL 握手时需要先设置 SSL SNI 字段,SNI 字段中既有域名信息,又有加密串信息,当服务端收到该 SNI 串时,从中取出加密及域名信息后,先验证加密数据的合法性,验证通过则进行 SSL 握手,否则禁止 SSL 握手,从而避免浪费 CPU 计算资源。下面是 SSL 客户端的简单示例:</p>
336-
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs c++"><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">ssl_handshake</span><span class="hljs-params">(acl::sslbase_conf&amp; conf, acl::socket_stream&amp; conn)</span> </span>&#123;<br> acl::sslbase_io* ssl = conf.<span class="hljs-built_in">create</span>(<span class="hljs-literal">false</span>);<br> <span class="hljs-type">const</span> <span class="hljs-type">char</span>* sni = <span class="hljs-string">&quot;crypted_token|mytest.com&quot;</span>;<br> ssl-&gt;<span class="hljs-built_in">set_sni_host</span>(sni); <span class="hljs-comment">// 设置 SNI 字段</span><br> <span class="hljs-keyword">if</span> (conn.<span class="hljs-built_in">setup_hook</span>(ssl) == ssl) &#123;<br> <span class="hljs-comment">// SSL 握手失败,销毁 SSL IO 对象。</span><br> ssl-&gt;<span class="hljs-built_in">destroy</span>();<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> &#125;<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>&#125;<br></code></pre></td></tr></table></figure>
336+
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><code class="hljs c++"><br><span class="hljs-function"><span class="hljs-type">bool</span> <span class="hljs-title">ssl_handshake</span><span class="hljs-params">(acl::sslbase_conf&amp; conf, acl::socket_stream&amp; conn)</span> </span>&#123;<br> acl::sslbase_io* ssl = conf.<span class="hljs-built_in">create</span>(<span class="hljs-literal">false</span>);<br> <span class="hljs-type">const</span> <span class="hljs-type">char</span>* sni = <span class="hljs-string">&quot;crypted_token|mytest.com&quot;</span>; <span class="hljs-comment">// 期中的加密token将由服务端验证</span><br> ssl-&gt;<span class="hljs-built_in">set_sni_host</span>(sni); <span class="hljs-comment">// 设置 SNI 字段</span><br> <span class="hljs-keyword">if</span> (conn.<span class="hljs-built_in">setup_hook</span>(ssl) == ssl) &#123;<br> <span class="hljs-comment">// SSL 握手失败,销毁 SSL IO 对象。</span><br> ssl-&gt;<span class="hljs-built_in">destroy</span>();<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;<br> &#125;<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;<br>&#125;<br></code></pre></td></tr></table></figure>
337337

338338
<h3 id="3-3、参考"><a href="#3-3、参考" class="headerlink" title="3.3、参考"></a>3.3、参考</h3><ul>
339339
<li>Acl 库下载: <a target="_blank" rel="noopener" href="https://github.com/acl-dev/acl/">https://github.com/acl-dev/acl/</a></li>
340340
<li>客户端示例:acl&#x2F;lib_acl_cpp&#x2F;samples&#x2F;ssl&#x2F;client</li>
341341
<li>服务端示例:acl&#x2F;lib_acl_cpp&#x2F;samples&#x2F;ssl&#x2F;server</li>
342342
<li>使用SSL中对数据进行加密传输:<a href="https://acl-dev.cn/2020/01/15/ssl/">https://acl-dev.cn/2020/01/15/ssl/</a></li>
343+
<li>Acl库下载:<a target="_blank" rel="noopener" href="https://github.com/acl-dev/acl/">https://github.com/acl-dev/acl/</a></li>
343344
</ul>
344345

345346

@@ -431,6 +432,12 @@ <h3 id="3-3、参考"><a href="#3-3、参考" class="headerlink" title="3.3、
431432
<article class="post-prev col-6">
432433

433434

435+
<a href="/2024/09/24/fiber_qt/" title="在 QT 界面编程中使用协程">
436+
<i class="iconfont icon-arrowleft"></i>
437+
<span class="hidden-mobile">在 QT 界面编程中使用协程</span>
438+
<span class="visible-mobile">上一篇</span>
439+
</a>
440+
434441
</article>
435442
<article class="post-next col-6">
436443

0 commit comments

Comments
 (0)