<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>SWEET&#39;S BLOG</title>
    <link>http://localhost:1336/</link>
    <description>Recent content from SWEET&#39;S BLOG</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    
    <managingEditor>1401617591@qq.com (sweet)</managingEditor>
    <webMaster>1401617591@qq.com (sweet)</webMaster>
    
    <copyright>本博客所有文章除特别声明外，均采用 BY-NC-SA 许可协议。转载请注明出处！</copyright>
    
    <lastBuildDate>Tue, 30 Dec 2025 14:30:00 +0800</lastBuildDate>
    
    
    <atom:link href="http://localhost:1336/index.xml" rel="self" type="application/rss&#43;xml" />
    

    
    

    <item>
      <title>OpenSSL玩转X.509证书🐾</title>
      <link>http://localhost:1336/post/%E8%AF%81%E4%B9%A6%E6%93%8D%E4%BD%9C/</link>
      <pubDate>Tue, 30 Dec 2025 14:30:00 &#43;0800</pubDate>
      <author>1401617591@qq.com (sweet)</author>
      <guid>http://localhost:1336/post/%E8%AF%81%E4%B9%A6%E6%93%8D%E4%BD%9C/</guid>
      <description>
        <![CDATA[<h1>OpenSSL玩转X.509证书🐾</h1><p>作者：sweet（1401617591@qq.com）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><p>hello！欢迎回到咪猫魔法世界~ 🐾✨</p>
<p>上篇文章中我们学习了DH协议的身份验证，可新问题来了：Bob怎么可信地获取Alice的公钥？如果中间人伪造公钥，之前的安全逻辑不就崩塌了？这时候X.509证书就该登场啦！</p>
<p>本文主打一个“实操+踩坑实录”——精细拆解X.509证书格式、区分DER/PEM格式、用OpenSSL做证书解析/私钥解析/签名验证，同时夹杂为大家分享一些让我折腾良久的血泪踩坑经历，帮助大家更好的理解、掌握证书操作。</p>
<hr>
<h2 id="一x509证书让公钥可信的核心载体">
<a class="header-anchor" href="#%e4%b8%80x509%e8%af%81%e4%b9%a6%e8%ae%a9%e5%85%ac%e9%92%a5%e5%8f%af%e4%bf%a1%e7%9a%84%e6%a0%b8%e5%bf%83%e8%bd%bd%e4%bd%93"></a>
一、X.509证书：让公钥“可信”的核心载体
</h2><p>X.509是公钥基础设施（PKI）的数字证书标准，核心使命就是解决“公钥可信分发”——通过可信第三方（CA）的签名，担保“实体身份 ↔ 公钥”的绑定关系，让接收方放心使用公钥。</p>
<h3 id="11-证书的核心组成rsa场景">
<a class="header-anchor" href="#11-%e8%af%81%e4%b9%a6%e7%9a%84%e6%a0%b8%e5%bf%83%e7%bb%84%e6%88%90rsa%e5%9c%ba%e6%99%af"></a>
1.1 证书的核心组成（RSA场景）
</h3><p>X.509证书本质是“身份信息+公钥+CA签名”的组合包，关键部分如下：</p>
<ol>
<li><strong>身份与有效期</strong>：
<ul>
<li>颁发者（Issuer）：谁签的证书（比如“某根CA机构”）；</li>
<li>主体（Subject）：证书属于谁（比如“www.example.com服务器”）；</li>
<li>有效期：证书生效和过期时间，过期后失效。</li>
</ul>
</li>
<li><strong>公钥与算法（RSA核心）</strong>：
<ul>
<li>公钥算法：明确使用RSA；</li>
<li>公钥内容：包含RSA的模数n和公指数e（常用65537），是加密/签名的核心参数。</li>
</ul>
</li>
<li><strong>CA的数字签名</strong>：
CA用自己的私钥，对“身份、公钥、有效期”等信息签名。其他人用CA的公钥验证签名，就能确认“证书未被篡改，公钥确实属于这个主体”。</li>
</ol>
<blockquote>
<p>咪猫小知识：CA（Certificate Authority）是受信任的证书颁发机构，比如百度HTTPS证书由GlobalSign颁发，我们常用的SSL证书都来自这类权威机构。</p>
</blockquote>
<h3 id="12-典型应用场景https通信">
<a class="header-anchor" href="#12-%e5%85%b8%e5%9e%8b%e5%ba%94%e7%94%a8%e5%9c%ba%e6%99%afhttps%e9%80%9a%e4%bf%a1"></a>
1.2 典型应用场景（HTTPS通信）
</h3><ol>
<li>服务器向客户端发送X.509证书；</li>
<li>客户端验证证书：CA签名是否合法、有效期是否有效、域名是否匹配；</li>
<li>验证通过后，客户端用证书中的RSA公钥加密“预主密钥”；</li>
<li>服务器用自身RSA私钥解密，双方基于预主密钥生成会话密钥，安全通信。</li>
</ol>
<hr>
<h2 id="二der与pem证书的两种存储格式">
<a class="header-anchor" href="#%e4%ba%8cder%e4%b8%8epem%e8%af%81%e4%b9%a6%e7%9a%84%e4%b8%a4%e7%a7%8d%e5%ad%98%e5%82%a8%e6%a0%bc%e5%bc%8f"></a>
二、DER与PEM：证书的两种“存储格式”
</h2><p>DER和PEM不是证书内容的区别，而是“存储X.509二进制数据”的两种方式，实际操作中经常要切换，必须要分清奥！</p>
<h3 id="21-格式核心对比">
<a class="header-anchor" href="#21-%e6%a0%bc%e5%bc%8f%e6%a0%b8%e5%bf%83%e5%af%b9%e6%af%94"></a>
2.1 格式核心对比
</h3><table>
  <thead>
      <tr>
          <th>对比项</th>
          <th>DER 格式</th>
          <th>PEM 格式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>编码方式</td>
          <td>二进制直接存储</td>
          <td>Base64编码（转成可打印文本）</td>
      </tr>
      <tr>
          <td>可读性</td>
          <td>二进制，文本编辑器打开是乱码</td>
          <td>文本格式，可直接阅读，开头/结尾有固定标记</td>
      </tr>
      <tr>
          <td>固定标记</td>
          <td>无</td>
          <td>开头：<code>-----BEGIN CERTIFICATE-----</code>；结尾：<code>-----END CERTIFICATE-----</code>（私钥/签名有对应标记）</td>
      </tr>
      <tr>
          <td>典型场景</td>
          <td>系统内部、程序间二进制交互</td>
          <td>文本环境传输（配置文件、邮件）、OpenSSL常用</td>
      </tr>
  </tbody>
</table>
<h3 id="22-关键提醒">
<a class="header-anchor" href="#22-%e5%85%b3%e9%94%ae%e6%8f%90%e9%86%92"></a>
2.2 关键提醒
</h3><ul>
<li>后缀不绝对：.cer/.crt可能是DER或PEM格式，需根据编码判断；</li>
<li>转换方法：OpenSSL可实现两种格式互转（后面实操会讲）。</li>
</ul>
<hr>
<h2 id="三openssl实操证书解析私钥解析签名验证">
<a class="header-anchor" href="#%e4%b8%89openssl%e5%ae%9e%e6%93%8d%e8%af%81%e4%b9%a6%e8%a7%a3%e6%9e%90%e7%a7%81%e9%92%a5%e8%a7%a3%e6%9e%90%e7%ad%be%e5%90%8d%e9%aa%8c%e8%af%81"></a>
三、OpenSSL实操：证书解析+私钥解析+签名验证
</h2><p>证书操作的核心工具是OpenSSL，下面的操作完全基于实际踩坑经历，步骤清晰，直接照做就行！</p>
<h3 id="31-准备工作">
<a class="header-anchor" href="#31-%e5%87%86%e5%a4%87%e5%b7%a5%e4%bd%9c"></a>
3.1 准备工作
</h3><ul>
<li>安装OpenSSL：Windows下载Win64 OpenSSL，安装后配置环境变量（或直接在安装目录的bin文件夹打开命令行）；</li>
<li>准备文件：获取证书文件（如rsa_private.pem），确保文件完整（避免多余字符）。</li>
</ul>
<h3 id="32-核心操作命令win64环境">
<a class="header-anchor" href="#32-%e6%a0%b8%e5%bf%83%e6%93%8d%e4%bd%9c%e5%91%bd%e4%bb%a4win64%e7%8e%af%e5%a2%83"></a>
3.2 核心操作命令（Win64环境）
</h3><h4 id="1-解析rsa私钥pem格式">
<a class="header-anchor" href="#1-%e8%a7%a3%e6%9e%90rsa%e7%a7%81%e9%92%a5pem%e6%a0%bc%e5%bc%8f"></a>
1. 解析RSA私钥（PEM格式）
</h4><p>命令：</p>
        
        <hr><p>本文2025-12-30首发于<a href='http://localhost:1336/'>SWEET'S BLOG</a>，最后修改于2025-12-30</p>]]>
      </description>
      
        <category>ctf-crypto</category>
      
    </item>
    
    

    <item>
      <title>维纳攻击(Wiener&#39;s Attack)🐾</title>
      <link>http://localhost:1336/post/%E7%BB%B4%E7%BA%B3%E6%94%BB%E5%87%BB/</link>
      <pubDate>Sun, 28 Dec 2025 15:30:00 &#43;0800</pubDate>
      <author>1401617591@qq.com (sweet)</author>
      <guid>http://localhost:1336/post/%E7%BB%B4%E7%BA%B3%E6%94%BB%E5%87%BB/</guid>
      <description>
        <![CDATA[<h1>维纳攻击(Wiener's Attack)🐾</h1><p>作者：sweet（1401617591@qq.com）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><p>hello！欢迎回到咪猫魔法世界~ 🐾✨</p>
<p>RSA的安全看似靠“大数分解”撑着，但如果私钥d选得太短，就会被维纳攻击轻松破解！本文专门拆解了维纳攻击的核心逻辑——用连分数逼近找到短小的d，不用分解n就能直接拿到私钥（cool），并在文末给出了完整代码和CTF例题，全程带着“踩坑实录”，帮新来的师傅们搞懂“为什么d短了就不安全”。</p>
<p>我们之前已经了解过了 RSA 的各种攻击，而维纳攻击算是“剑走偏锋”的一种，核心依赖数论里的连分数工具，看似复杂，实则思路超清晰——不过如果我们能掌握“连分数+收敛子验证”，这类题也是能拿下的。</p>
<hr>
<h2 id="一前置知识连分数维纳攻击的核心工具">
<a class="header-anchor" href="#%e4%b8%80%e5%89%8d%e7%bd%ae%e7%9f%a5%e8%af%86%e8%bf%9e%e5%88%86%e6%95%b0%e7%bb%b4%e7%ba%b3%e6%94%bb%e5%87%bb%e7%9a%84%e6%a0%b8%e5%bf%83%e5%b7%a5%e5%85%b7"></a>
一、前置知识：连分数——维纳攻击的核心工具
</h2><p>维纳攻击的本质是“用连分数逼近有理数”，所以先搞懂连分数的基础，攻击原理就顺理成章了。</p>
<h3 id="11-连分数的定义">
<a class="header-anchor" href="#11-%e8%bf%9e%e5%88%86%e6%95%b0%e7%9a%84%e5%ae%9a%e4%b9%89"></a>
1.1 连分数的定义
</h3><p>连分数是一种特殊的分数表示形式，通过整数与单位分数（分子为1的分数）递归嵌套表达，比如正分数\(a/b\)可展开为：
</p>
\[
x = a_0 + \frac{1}{a_1 + \frac{1}{a_2 + \frac{1}{a_3 + \ddots}}}
\]<p>
简记为\([a_0; a_1, a_2, ..., a_k]\)，其中\(a_0\)是整数部分，\(a_1,a_2,...,a_k\)是正整数“部分商”。</p>
<p>举个例子：\(11/35\)的连分数展开为\([0; 3, 5, 2]\)，计算过程如下：</p>
<ol>
<li>\(35 ÷ 11 = 3\) 余 \(2\) → 部分商\(a_0=0\)，剩余\(2/11\)；</li>
<li>\(11 ÷ 2 = 5\) 余 \(1\) → 部分商\(a_1=3\)，剩余\(1/2\)；</li>
<li>\(2 ÷ 1 = 2\) 余 \(0\) → 部分商\(a_2=5\)，\(a_3=2\)，终止。</li>
</ol>
<h3 id="12-连分数的核心概念收敛子">
<a class="header-anchor" href="#12-%e8%bf%9e%e5%88%86%e6%95%b0%e7%9a%84%e6%a0%b8%e5%bf%83%e6%a6%82%e5%bf%b5%e6%94%b6%e6%95%9b%e5%ad%90"></a>
1.2 连分数的核心概念：收敛子
</h3><p>收敛子是“截取连分数前n项部分商”得到的近似分数，记为\(h_n/m_n\)（\(h_n\)为分子，\(m_n\)为分母）。它的关键性质是：</p>
<ul>
<li>逼近精度随项数增加而提高，交替大于、小于原分数；</li>
<li>是原分数的“最优逼近”——没有分母更小的分数能比收敛子更接近原分数。</li>
</ul>
<p>比如\(11/35\)的收敛子：</p>
        
        <hr><p>本文2025-12-28首发于<a href='http://localhost:1336/'>SWEET'S BLOG</a>，最后修改于2025-12-28</p>]]>
      </description>
      
        <category>ctf-crypto</category>
      
    </item>
    
    

    <item>
      <title>密钥交换的魔法：DH协议与STS协议🐾</title>
      <link>http://localhost:1336/post/dh%E5%8D%8F%E8%AE%AE/</link>
      <pubDate>Thu, 25 Dec 2025 16:00:00 &#43;0800</pubDate>
      <author>1401617591@qq.com (sweet)</author>
      <guid>http://localhost:1336/post/dh%E5%8D%8F%E8%AE%AE/</guid>
      <description>
        <![CDATA[<h1>密钥交换的魔法：DH协议与STS协议🐾</h1><p>作者：sweet（1401617591@qq.com）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><p>hello！欢迎回到咪猫魔法世界~ 🐾✨</p>
<p>在不安全的网络里，怎么安全交换只有双方知道的共享密钥？这就轮到DH协议登场啦！它能在被监听的信道上，让通信双方算出相同的密钥，却让窃听者无从下手——核心秘诀就是“离散对数难题”的魔力~o( =∩ω∩= )m～</p>
<p>本文专门拆解DH协议的基础原理、中间人攻击的漏洞，以及简化STS协议的防护方案，还给出了可直接运行的Python代码，全程保持“边学边踩坑”的真实感，帮助各位新手师傅们搞懂密钥交换的核心逻辑！</p>
<hr>
<h2 id="一dh协议基础不安全信道的密钥魔法">
<a class="header-anchor" href="#%e4%b8%80dh%e5%8d%8f%e8%ae%ae%e5%9f%ba%e7%a1%80%e4%b8%8d%e5%ae%89%e5%85%a8%e4%bf%a1%e9%81%93%e7%9a%84%e5%af%86%e9%92%a5%e9%ad%94%e6%b3%95"></a>
一、DH协议基础：不安全信道的密钥魔法
</h2><p>DH协议（Diffie-Hellman协议）是密钥交换的经典方案，1976年由Whitfield Diffie和Martin Hellman提出，核心是“公开参数+私有计算”，让双方在不泄露私钥的情况下，协商出共享密钥。</p>
<h3 id="11-核心原理离散对数难题">
<a class="header-anchor" href="#11-%e6%a0%b8%e5%bf%83%e5%8e%9f%e7%90%86%e7%a6%bb%e6%95%a3%e5%af%b9%e6%95%b0%e9%9a%be%e9%a2%98"></a>
1.1 核心原理：离散对数难题
</h3><p>DH协议的安全性完全依赖“离散对数问题”的困难性：</p>
<ul>
<li>已知大素数p、模p的本原根g（g的幂能生成模p的所有非零剩余类），以及 \(g^a \pmod{p}\)，想反推出私钥a，在p足够大时几乎不可能（暴力破解无效）；</li>
<li>正向计算很简单：已知a，计算 \(g^a \pmod{p}\) 高效可行。</li>
</ul>
<h3 id="12-dh协议流程基础原始版">
<a class="header-anchor" href="#12-dh%e5%8d%8f%e8%ae%ae%e6%b5%81%e7%a8%8b%e5%9f%ba%e7%a1%80%e5%8e%9f%e5%a7%8b%e7%89%88"></a>
1.2 DH协议流程（基础原始版）
</h3><h4 id="文字版步骤">
<a class="header-anchor" href="#%e6%96%87%e5%ad%97%e7%89%88%e6%ad%a5%e9%aa%a4"></a>
文字版步骤：
</h4><ol>
<li>公开参数协商：双方先约定公开参数——大素数p和模p的本原根g（可公开传输，无需保密）；</li>
<li>私钥生成：
<ul>
<li>Alice生成私钥a（保密），计算公钥 \(A = g^a \pmod{p}\)，发给Bob；</li>
<li>Bob生成私钥b（保密），计算公钥 \(B = g^b \pmod{p}\)，发给Alice；</li>
</ul>
</li>
<li>共享密钥计算：
<ul>
<li>Alice用Bob的公钥B和自己的私钥a，计算 \(K = B^a \pmod{p} = (g^b)^a \pmod{p} = g^{ab} \pmod{p}\)；</li>
<li>Bob用Alice的公钥A和自己的私钥b，计算 \(K = A^b \pmod{p} = (g^a)^b \pmod{p} = g^{ab} \pmod{p}\)；</li>
</ul>
</li>
<li>结果：双方得到相同的共享密钥K，窃听者仅能获取p、g、A、B，无法推导K。</li>
</ol>
<h4 id="原理图解">
<a class="header-anchor" href="#%e5%8e%9f%e7%90%86%e5%9b%be%e8%a7%a3"></a>
原理图解：
</h4><pre tabindex="0"><code>Alice                  不安全信道                  Bob
  |                        |                        |
  |  生成私钥a，计算A=g^a mod p                  |
  |-------------------------------------------&gt;|
  |                        |                        |
  |                                          生成私钥b，计算B=g^b mod p
  |&lt;-------------------------------------------|
  |                        |                        |
  |  计算K=B^a mod p                          |
  |                        |                        |  计算K=A^b mod p
  |                        |                        |
  |  共享密钥K                                  共享密钥K
  |                        |                        |
</code></pre><h3 id="13-python代码实现">
<a class="header-anchor" href="#13-python%e4%bb%a3%e7%a0%81%e5%ae%9e%e7%8e%b0"></a>
1.3 Python代码实现
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">dh_simulate</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">g</span><span class="p">,</span> <span class="n">alice_a</span><span class="p">,</span> <span class="n">bob_b</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># 分别生成Alice和Bob的公钥</span>
</span></span><span class="line"><span class="cl">    <span class="n">alice_A</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">g</span><span class="p">,</span> <span class="n">alice_a</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">bob_B</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">g</span><span class="p">,</span> <span class="n">bob_b</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># 分别计算Alice和Bob的共享密钥</span>
</span></span><span class="line"><span class="cl">    <span class="n">alice_shared</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">bob_B</span><span class="p">,</span> <span class="n">alice_a</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">bob_shared</span> <span class="o">=</span> <span class="nb">pow</span><span class="p">(</span><span class="n">alice_A</span><span class="p">,</span> <span class="n">bob_b</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># 验证双方计算出的共享密钥是否一致</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># 若共享密钥不一致，说明可能遭受中间人攻击，模拟失败</span>
</span></span><span class="line"><span class="cl">    <span class="k">assert</span> <span class="n">alice_shared</span> <span class="o">==</span> <span class="n">bob_shared</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">alice_shared</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 手动输入p、g、alice_a、bob_b（可替换为大素数和大私钥）</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="mi">23</span>  <span class="c1"># 模素数（实际应用需用2048位以上大素数）</span>
</span></span><span class="line"><span class="cl"><span class="n">g</span> <span class="o">=</span> <span class="mi">5</span>   <span class="c1"># 模23的本原根（5的幂能生成1~22所有数）</span>
</span></span><span class="line"><span class="cl"><span class="n">alice_a</span> <span class="o">=</span> <span class="mi">6</span>  <span class="c1"># Alice的私钥（保密）</span>
</span></span><span class="line"><span class="cl"><span class="n">bob_b</span> <span class="o">=</span> <span class="mi">15</span>   <span class="c1"># Bob的私钥（保密）</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">shared_key</span> <span class="o">=</span> <span class="n">dh_simulate</span><span class="p">(</span><span class="n">p</span><span class="p">,</span> <span class="n">g</span><span class="p">,</span> <span class="n">alice_a</span><span class="p">,</span> <span class="n">bob_b</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;公共参数:p=</span><span class="si">{</span><span class="n">p</span><span class="si">}</span><span class="s2">, g=</span><span class="si">{</span><span class="n">g</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Alice的私钥:</span><span class="si">{</span><span class="n">alice_a</span><span class="si">}</span><span class="s2">, 公钥:</span><span class="si">{</span><span class="nb">pow</span><span class="p">(</span><span class="n">g</span><span class="p">,</span> <span class="n">alice_a</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;Bob的私钥:</span><span class="si">{</span><span class="n">bob_b</span><span class="si">}</span><span class="s2">, 公钥:</span><span class="si">{</span><span class="nb">pow</span><span class="p">(</span><span class="n">g</span><span class="p">,</span> <span class="n">bob_b</span><span class="p">,</span> <span class="n">p</span><span class="p">)</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;共享密钥:</span><span class="si">{</span><span class="n">shared_key</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h4 id="运行结果">
<a class="header-anchor" href="#%e8%bf%90%e8%a1%8c%e7%bb%93%e6%9e%9c"></a>
运行结果：
</h4><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-Python" data-lang="Python"><span class="line"><span class="cl"><span class="n">公共参数</span><span class="p">:</span><span class="n">p</span><span class="o">=</span><span class="mi">23</span><span class="p">,</span> <span class="n">g</span><span class="o">=</span><span class="mi">5</span>
</span></span><span class="line"><span class="cl"><span class="n">Alice的私钥</span><span class="p">:</span><span class="mi">6</span><span class="p">,</span> <span class="n">公钥</span><span class="p">:</span><span class="mi">8</span>
</span></span><span class="line"><span class="cl"><span class="n">Bob的私钥</span><span class="p">:</span><span class="mi">15</span><span class="p">,</span> <span class="n">公钥</span><span class="p">:</span><span class="mi">19</span>
</span></span><span class="line"><span class="cl"><span class="n">共享密钥</span><span class="p">:</span><span class="mi">2</span>
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="二致命漏洞中间人攻击如何破解dh协议">
<a class="header-anchor" href="#%e4%ba%8c%e8%87%b4%e5%91%bd%e6%bc%8f%e6%b4%9e%e4%b8%ad%e9%97%b4%e4%ba%ba%e6%94%bb%e5%87%bb%e5%a6%82%e4%bd%95%e7%a0%b4%e8%a7%a3dh%e5%8d%8f%e8%ae%ae"></a>
二、致命漏洞：中间人攻击如何破解DH协议？
</h2><p>基础DH协议看似完美，但有个致命缺陷——<strong>缺乏身份验证</strong>，中间人能轻松篡改公钥，窃取通信内容！</p>
        
        <hr><p>本文2025-12-25首发于<a href='http://localhost:1336/'>SWEET'S BLOG</a>，最后修改于2025-12-25</p>]]>
      </description>
      
        <category>ctf-crypto</category>
      
    </item>
    
    

    <item>
      <title>二次剩余与勒让德符号🐾</title>
      <link>http://localhost:1336/post/%E4%BA%8C%E6%AC%A1%E5%89%A9%E4%BD%99%E4%B8%8E%E5%8B%92%E8%AE%A9%E5%BE%B7%E7%AC%A6%E5%8F%B7/</link>
      <pubDate>Mon, 22 Dec 2025 15:30:00 &#43;0800</pubDate>
      <author>1401617591@qq.com (sweet)</author>
      <guid>http://localhost:1336/post/%E4%BA%8C%E6%AC%A1%E5%89%A9%E4%BD%99%E4%B8%8E%E5%8B%92%E8%AE%A9%E5%BE%B7%E7%AC%A6%E5%8F%B7/</guid>
      <description>
        <![CDATA[<h1>二次剩余与勒让德符号🐾</h1><p>作者：sweet（1401617591@qq.com）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><p>hello！欢迎回到咪猫魔法世界~ 🐾✨</p>
<p>信安人绕不开的“数论坎”来啦！前面学完一次同余方程，本以为可以顺风顺水，结果碰到二次同余直接懵圈——怎么一次到二次，解法复杂度直接翻倍啊？！</p>
<p>这篇blog是上一篇《信安数学基础学习与练习》的专项补强，专门拆解二次同余方程、二次剩余、勒让德符号这些“拦路虎”，还会和一次同余做详细对比，帮大家理清逻辑。全程保持真实踩坑感，毕竟“懂（不）了”才是学习数论的常态嘛！</p>
<hr>
<h2 id="一二次同余方程从一次到二次解法的蜕变">
<a class="header-anchor" href="#%e4%b8%80%e4%ba%8c%e6%ac%a1%e5%90%8c%e4%bd%99%e6%96%b9%e7%a8%8b%e4%bb%8e%e4%b8%80%e6%ac%a1%e5%88%b0%e4%ba%8c%e6%ac%a1%e8%a7%a3%e6%b3%95%e7%9a%84%e8%9c%95%e5%8f%98"></a>
一、二次同余方程：从一次到二次解法的“蜕变”
</h2><blockquote>
<p>一次同余方程靠扩展欧几里得就能直接冲，可二次同余完全不一样！核心逻辑是“拆解+合并”，先把复杂模数拆成简单素数幂，解完再用中国剩余定理合并，一步都不能省。</p>
</blockquote>
<h3 id="11-二次同余方程核心原理">
<a class="header-anchor" href="#11-%e4%ba%8c%e6%ac%a1%e5%90%8c%e4%bd%99%e6%96%b9%e7%a8%8b%e6%a0%b8%e5%bf%83%e5%8e%9f%e7%90%86"></a>
1.1 二次同余方程核心原理
</h3><p>二次同余方程的一般形式是 \(ax^2 + bx + c \equiv 0 \pmod{m}\)，最简形式是 \(x^2 \equiv a \pmod{m}\)（a、m为整数，\(m>0\)）。</p>
<p>核心思路就两步：</p>
<ol>
<li>模数分解：根据“素数幂分解定理”，把m拆成 \(m = p_1^{k_1} \times p_2^{k_2} \times ... \times p_n^{k_n}\)（\(p_i\) 是素数）；</li>
<li>合并解：原方程等价于“模每个素数幂 \(p_i^{k_i}\) 的同余方程组”，解完每个方程组后，用中国剩余定理合并出最终解。</li>
</ol>
<blockquote>
<p>Q: 为啥要这么拆？
A: 直接解模合数m的方程太难了！素数幂的方程更简单，拆解后难度直接降级🐱</p>
</blockquote>
<h3 id="12-一次-vs-二次同余方程">
<a class="header-anchor" href="#12-%e4%b8%80%e6%ac%a1-vs-%e4%ba%8c%e6%ac%a1%e5%90%8c%e4%bd%99%e6%96%b9%e7%a8%8b"></a>
1.2 一次 vs 二次同余方程
</h3><p>为了避免混淆，我把两者的关键差异整理成了表格，一目了然：</p>
<table>
  <thead>
      <tr>
          <th>对比维度</th>
          <th>一次同余方程</th>
          <th>二次同余方程</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>方程形式</td>
          <td>\(ax \equiv b \pmod{m}\)（a、m为整数，\(m>0\)）</td>
          <td>一般形式：\(ax^2 + bx + c \equiv 0 \pmod{m}\)；最简形式：\(x^2 \equiv a \pmod{m}\)</td>
      </tr>
      <tr>
          <td>解的存在性判断</td>
          <td>简单！计算\(\gcd(a,m)\)，若能整除b则有解</td>
          <td>复杂！先拆m为素数幂，再用勒让德符号/欧拉判别法判断每个素数幂下是否有解，最后看所有方程组是否都有解</td>
      </tr>
      <tr>
          <td>核心解法工具</td>
          <td>1. 扩展欧几里得算法（求特解）；2. 中国剩余定理（合并解）</td>
          <td>1. 勒让德/雅可比符号（判断可解性）；2. 亨泽尔引理（提升素数解到素数幂解）；3. Tonelli-Shanks算法（求素数模下的解）；4. 中国剩余定理（合并解）</td>
      </tr>
      <tr>
          <td>解的数量与结构</td>
          <td>若有解，设\(d=\gcd(a,m)\)，则模m下有d个不同解；解的结构：\(x \equiv x_0 + k \times m/d \pmod{m}\)（\(k=0,1,...,d-1\)），规律明确</td>
          <td>模素数p（\(p \nmid a\)）：有解则通常2个解；\(x^2 \equiv 0 \pmod{p}\) 仅有1个解\(x \equiv 0\)；模素数幂\(p^k\)：解数可能为0、1或2；模合数m：解数是各素数幂解数的乘积，无统一规律</td>
      </tr>
      <tr>
          <td>复杂度与应用</td>
          <td>复杂度低，直接用于RSA求模逆元等场景</td>
          <td>复杂度高，依赖大数分解；二次剩余的判断困难性是Goldwasser-Micali概率加密的安全基础，求解算法（如Tonelli-Shanks）用于椭圆曲线密码</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="二二次剩余平方同余有解的专属名字">
<a class="header-anchor" href="#%e4%ba%8c%e4%ba%8c%e6%ac%a1%e5%89%a9%e4%bd%99%e5%b9%b3%e6%96%b9%e5%90%8c%e4%bd%99%e6%9c%89%e8%a7%a3%e7%9a%84%e4%b8%93%e5%b1%9e%e5%90%8d%e5%ad%97"></a>
二、二次剩余：平方同余有解的“专属名字”
</h2><p>搞懂二次同余，核心就是搞懂“二次剩余”——本质就是判断“\(x^2 \equiv a \pmod{p}\) 有没有解”</p>
        
        <hr><p>本文2025-12-22首发于<a href='http://localhost:1336/'>SWEET'S BLOG</a>，最后修改于2025-12-22</p>]]>
      </description>
      
        <category>ctf-math</category>
      
    </item>
    
    

    <item>
      <title>RSA基础与大数分解（含多种类型exp）🐾</title>
      <link>http://localhost:1336/post/rsa%E5%9F%BA%E7%A1%80%E9%A2%98%E8%A7%A3/</link>
      <pubDate>Sun, 21 Dec 2025 14:00:00 &#43;0800</pubDate>
      <author>1401617591@qq.com (sweet)</author>
      <guid>http://localhost:1336/post/rsa%E5%9F%BA%E7%A1%80%E9%A2%98%E8%A7%A3/</guid>
      <description>
        <![CDATA[<h1>RSA基础与大数分解（含多种类型exp）🐾</h1><p>作者：sweet（1401617591@qq.com）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><p>hello！欢迎回到咪猫魔法世界~ 🐾✨</p>
<p>前面啃完数论基础和CryptoHack入门题，这篇聚焦RSA核心——它是1977年由Ron Rivest、Adi Shamir和Leonard Adleman提出的非对称加密算法，本质是数论知识点（欧拉函数、模逆元、大质数判断）的拼接。另外我在这篇文章中还对 RSA安全基石、更多CTF攻击类型、实际应用场景和实战工具等进行了整合，让大家通过这一篇文章就能够大概了解多种 RSA 的“原理+实战+拓展”实际应用~</p>
<hr>
<h2 id="一rsa加密算法基础">
<a class="header-anchor" href="#%e4%b8%80rsa%e5%8a%a0%e5%af%86%e7%ae%97%e6%b3%95%e5%9f%ba%e7%a1%80"></a>
一、RSA加密算法基础
</h2><h3 id="11-核心定义与安全基石">
<a class="header-anchor" href="#11-%e6%a0%b8%e5%bf%83%e5%ae%9a%e4%b9%89%e4%b8%8e%e5%ae%89%e5%85%a8%e5%9f%ba%e7%9f%b3"></a>
1.1 核心定义与安全基石
</h3><p>RSA是非对称加密算法的经典代表，加密和解密使用不同密钥，安全性完全建立在“大数分解难题”之上。</p>
<ul>
<li>正向计算容易：两个大质数p、q相乘得到n，操作简单高效；</li>
<li>逆向推导极难：已知n，想分解出p和q，以当前经典计算能力需数百年甚至更久，这构成了RSA的安全防线。</li>
</ul>
<h3 id="12-rsa-的核心流程">
<a class="header-anchor" href="#12-rsa-%e7%9a%84%e6%a0%b8%e5%bf%83%e6%b5%81%e7%a8%8b"></a>
1.2 RSA 的核心流程
</h3><h4 id="121-密钥生成">
<a class="header-anchor" href="#121-%e5%af%86%e9%92%a5%e7%94%9f%e6%88%90"></a>
1.2.1 密钥生成
</h4><ol>
<li>选两个不相等大质数p、q（CTF中常见1024/2048位，实际推荐2048位以上）；</li>
<li>算模数$n = p \times q$（公钥/私钥共用核心模数）；</li>
<li>算欧拉函数$\phi(n) = (p-1)(q-1)$（若n为多素数乘积，$\phi(n)$为各素数减1的乘积）；</li>
<li>选公钥e：满足$1 < e < \phi(n)$且$\gcd(e,\phi(n))=1$，常用65537（费马素数），避免用3/17等小指数；</li>
<li>算私钥d：d是e的模逆元，即$e \times d \equiv 1 \pmod{\phi(n)}$，可通过多种方法求解（如下文方法）。</li>
</ol>
<p>✅ 最终：公钥$(e,n)$公开（用于加密/验签），私钥$(d,n)$保密（用于解密/签名）。</p>
<h4 id="122-加密解密">
<a class="header-anchor" href="#122-%e5%8a%a0%e5%af%86%e8%a7%a3%e5%af%86"></a>
1.2.2 加密&amp;解密
</h4><ul>
<li>加密（公钥）：$c = m^e \pmod{n}$（m为明文，需满足$m < n$，否则需分组或填充）；</li>
<li>解密（私钥）：$m = c^d \pmod{n}$；</li>
<li>原理支撑：欧拉定理（$\gcd(m,n)=1$时，$m^{\phi(n)} \equiv 1 \pmod{n}$），因$e \times d = k \times \phi(n) + 1$，故$m^{e \times d} \equiv m \pmod{n}$。</li>
</ul>
<h4 id="123-核心特性与应用场景">
<a class="header-anchor" href="#123-%e6%a0%b8%e5%bf%83%e7%89%b9%e6%80%a7%e4%b8%8e%e5%ba%94%e7%94%a8%e5%9c%ba%e6%99%af"></a>
1.2.3 核心特性与应用场景
</h4><ul>
<li>非对称性：公钥加密只能私钥解密，私钥签名只能公钥验签，是应用核心；</li>
<li>典型用途：
<ol>
<li>密钥分发：HTTPS/SSL中，浏览器用服务器公钥加密临时会话密钥，后续用对称加密通信；</li>
<li>身份验证：SSH免密登录，本地私钥应答服务器公钥挑战；</li>
<li>数字签名：软件发布者用私钥签名哈希值，用户用公钥验签，确保软件未篡改。</li>
</ol>
</li>
</ul>
<h4 id="124-模逆元的三种求解方法">
<a class="header-anchor" href="#124-%e6%a8%a1%e9%80%86%e5%85%83%e7%9a%84%e4%b8%89%e7%a7%8d%e6%b1%82%e8%a7%a3%e6%96%b9%e6%b3%95"></a>
1.2.4 模逆元的三种求解方法
</h4><p>除了扩展欧几里得算法，模逆元还有两种常用求法，适配不同场景：</p>
        
        <hr><p>本文2025-12-21首发于<a href='http://localhost:1336/'>SWEET'S BLOG</a>，最后修改于2025-12-21</p>]]>
      </description>
      
        <category>ctf-crypto</category>
      
    </item>
    
    

    <item>
      <title>信安数学基础学习与练习</title>
      <link>http://localhost:1336/post/%E4%BF%A1%E5%AE%89%E6%95%B0%E5%AD%A6%E5%9F%BA%E7%A1%80%E5%AD%A6%E4%B9%A0/</link>
      <pubDate>Mon, 15 Dec 2025 14:00:00 &#43;0800</pubDate>
      <author>1401617591@qq.com (sweet)</author>
      <guid>http://localhost:1336/post/%E4%BF%A1%E5%AE%89%E6%95%B0%E5%AD%A6%E5%9F%BA%E7%A1%80%E5%AD%A6%E4%B9%A0/</guid>
      <description>
        <![CDATA[<h1>信安数学基础学习与练习</h1><p>作者：sweet（1401617591@qq.com）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><p>hello！欢迎来到咪猫魔法世界~ 🐾✨</p>
<p>本篇内容参考了不少CSDN上的优质文章与笔记，我把核心知识点都提炼成了易懂的短句（可能略有偏差，但足够贴合初学理解）。其中包含具体示例、算法解析、构造方法的优质资料也都整合在文中啦，希望能给同样初学的师傅们一些帮助（若有理解上的偏差也希望师傅们及时指出！）~~o( =∩ω∩= )m</p>
<hr>
<h2 id="一信安数学基础学习">
<a class="header-anchor" href="#%e4%b8%80%e4%bf%a1%e5%ae%89%e6%95%b0%e5%ad%a6%e5%9f%ba%e7%a1%80%e5%ad%a6%e4%b9%a0"></a>
一、信安数学基础学习
</h2><h3 id="1-整除欧几里得除法与素数基本定理">
<a class="header-anchor" href="#1-%e6%95%b4%e9%99%a4%e6%ac%a7%e5%87%a0%e9%87%8c%e5%be%97%e9%99%a4%e6%b3%95%e4%b8%8e%e7%b4%a0%e6%95%b0%e5%9f%ba%e6%9c%ac%e5%ae%9a%e7%90%86"></a>
1. 整除、欧几里得除法与素数基本定理
</h3><ul>
<li>
<p><strong>整除</strong>：若a÷b=c无余数，则称b整除a（记为b∣a），商为c。</p>
</li>
<li>
<p>关键性质：</p>
<ul>
<li>传递性：如12能被6整除、6能被3整除，则12必能被3整除；</li>
<li>线性组合：如6能整除12和18，则6也能整除12×2+18×3=78（倍数的线性组合仍为倍数）。</li>
</ul>
</li>
<li>
<p><strong>欧几里得除法（带余除法）</strong>：a÷b=c余d（0&lt;d&lt;b），其中c和d是唯一确定的。</p>
</li>
<li>
<p>核心作用：是求最大公约数、解同余方程的基础，先固定除法的“商余关系”。</p>
</li>
<li>
<p><strong>最大公约数(gcd)与欧几里得算法(辗转相除法)</strong>：</p>
<ul>
<li>
<p>gcd定义：能同时整除a和b的最大整数，如gcd(198,252)=18；</p>
</li>
<li>
<p>特殊情况：若gcd(a,b)=1，则a和b互素（如4和5，仅1能同时整除）；</p>
</li>
<li>
<p>欧几里得算法：大数÷小数得余数，再用原除数÷余数，重复至余数为0，最后一个非零余数即为gcd；</p>
</li>
<li>
<p>示例：计算gcd(252,198)</p>
<p>①252÷198=1余54；</p>
<p>②198÷54=3余36；</p>
<p>③54÷36=1余18；</p>
<p>④36÷18=2余0</p>
<p>→ 最终gcd=18。</p>
</li>
</ul>
</li>
<li>
<p><strong>扩展欧几里得算法</strong>：</p>
<ul>
<li>核心能力：除求gcd(a,b)外，还能找到整数x、y满足a×x + b×y = gcd(a,b)；</li>
<li>计算方法：回代法——先通过欧几里得算法求gcd，再从最后一步反向回代，推导出满足等式的x、y；</li>
<li>注意点：若x为负数，需累加模数至x为正；</li>
<li>核心应用：求模逆元——若a和m互素（gcd(a,m)=1），可找到x使a×x ≡1 mod m（x即为a的逆元，如2×3=6≡1 mod5，3是2的逆元），是密码学解密的关键。</li>
</ul>
</li>
<li>
<p><strong>素数基本定理</strong>：</p>
<ul>
<li>核心结论：当x→∞时，不大于x的素数个数π(x)与x/lnx渐近等价（比值趋近于1）；</li>
<li>应用：用于计算欧拉函数、判断RSA等密码算法的安全性（依赖大素数难分解的特性）。</li>
</ul>
</li>
</ul>
<h3 id="2-同余与剩余系">
<a class="header-anchor" href="#2-%e5%90%8c%e4%bd%99%e4%b8%8e%e5%89%a9%e4%bd%99%e7%b3%bb"></a>
2. 同余与剩余系
</h3><ul>
<li>
<p><strong>同余</strong>：</p>
<ul>
<li>定义：若a和b除以m的余数相同，则称a≡b(mod m)（如17≡2 mod5），且a-b能被m整除；</li>
<li>核心性质：
<ul>
<li>加减乘不变：如3≡8 mod5、4≡9 mod5，则3+4=7≡8+9=17 mod5，3×4=12≡8×9=72 mod5；</li>
<li>消去律（有条件）：如2×3≡2×8 mod5，因2和5互素，可消去2得3≡8 mod5。</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>剩余系</strong>：</p>
<ul>
<li>完全剩余系：除以m能覆盖0~m-1所有余数的一组数（无遗漏、无重复）；</li>
<li>简化剩余系：从完全剩余系中筛选出与m互素的数，其个数为欧拉函数φ(m)；</li>
<li>示例：模6的完全剩余系为{0,1,2,3,4,5}，简化剩余系为{1,5}，故φ(6)=2。</li>
</ul>
</li>
</ul>
<h3 id="3-欧拉函数欧拉定理与费马小定理">
<a class="header-anchor" href="#3-%e6%ac%a7%e6%8b%89%e5%87%bd%e6%95%b0%e6%ac%a7%e6%8b%89%e5%ae%9a%e7%90%86%e4%b8%8e%e8%b4%b9%e9%a9%ac%e5%b0%8f%e5%ae%9a%e7%90%86"></a>
3. 欧拉函数、欧拉定理与费马小定理
</h3><ul>
<li>
<p><strong>欧拉函数φ(m)</strong>：1~m中与m互素的整数个数，如φ(6)=2。</p>
        
        <hr><p>本文2025-12-15首发于<a href='http://localhost:1336/'>SWEET'S BLOG</a>，最后修改于2025-12-15</p>]]>
      </description>
      
        <category>ctf-math</category>
      
    </item>
    
    

    <item>
      <title>哈希算法与文件隐写基础</title>
      <link>http://localhost:1336/post/%E5%93%88%E5%B8%8C%E7%AE%97%E6%B3%95%E4%B8%8E%E6%96%87%E4%BB%B6%E9%9A%90%E5%86%99%E5%9F%BA%E7%A1%80/</link>
      <pubDate>Mon, 08 Dec 2025 14:00:00 &#43;0800</pubDate>
      <author>1401617591@qq.com (sweet)</author>
      <guid>http://localhost:1336/post/%E5%93%88%E5%B8%8C%E7%AE%97%E6%B3%95%E4%B8%8E%E6%96%87%E4%BB%B6%E9%9A%90%E5%86%99%E5%9F%BA%E7%A1%80/</guid>
      <description>
        <![CDATA[<h1>哈希算法与文件隐写基础</h1><p>作者：sweet（1401617591@qq.com）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><p>hello！欢迎来到咪猫魔法世界~ 🐾✨</p>
<p>在 CTF 的 Crypto/Misc 里，<strong>哈希像“给数据按下的指纹印章”</strong>：你拿着印章（算法）一盖，谁来都能复现同一个指纹；而<strong>文件隐写</strong>更像“把小纸条塞进字节夹层里”——文件表面看着正常，里面却藏着另一份故事。
这两类题的共同点是：<strong>不靠玄学，靠流程</strong>。你只要会“看懂它是什么、再决定怎么下手”，分数就会自己跑过来（O.o）✨</p>
<hr>
<h2 id="一关于哈希--加密--编码">
<a class="header-anchor" href="#%e4%b8%80%e5%85%b3%e4%ba%8e%e5%93%88%e5%b8%8c--%e5%8a%a0%e5%af%86--%e7%bc%96%e7%a0%81"></a>
一、关于哈希 / 加密 / 编码
</h2><p>很多新手🐱栽的第一个坑，就是把这三者混成一锅粥（比如我曾经就在做ER图的时候写了这样一个词：“加密后的密文”，当时我们项目指导老师笑的嘴角就没压下来过555）。那么我们现在一起来理理这三者之间的关系，相信看完之后你会对三者之间的区别有一个更加清新的认识。</p>
<table>
  <thead>
      <tr>
          <th>对比维度</th>
          <th>哈希（Hash）</th>
          <th>加密（Encryption）</th>
          <th>编码（Encoding）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>能不能还原</td>
          <td><strong>理论上不可逆</strong>（只能撞/爆破/查表）</td>
          <td><strong>可逆</strong>（有密钥就能解）</td>
          <td><strong>可逆</strong>（公开规则就能解）</td>
      </tr>
      <tr>
          <td>主要目的</td>
          <td>完整性校验、唯一标识、指纹对比</td>
          <td>保密通信、保护内容</td>
          <td>适配传输/存储（显示、协议、字符集）</td>
      </tr>
      <tr>
          <td>常见例子</td>
          <td>MD5、SHA-1、SHA-256、CRC32</td>
          <td>AES、RSA</td>
          <td>Base64、URL Encode、UTF-8</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p>咪猫口诀：<strong>哈希“变不回去”，加密“有钥匙回去”，编码“大家都能回去”。</strong> 🐾</p>
</blockquote>
<p>这里要补一层更“比赛友好”的理解：
CTF 里说“破解哈希”，大多数时候其实不是从哈希值反推出原文（那是做梦），而是——<strong>你猜一堆可能的原文，把它们都盖一遍指纹，看看谁对上了</strong>。</p>
<hr>
<h2 id="二哈希到底强在哪里也脆在哪里">
<a class="header-anchor" href="#%e4%ba%8c%e5%93%88%e5%b8%8c%e5%88%b0%e5%ba%95%e5%bc%ba%e5%9c%a8%e5%93%aa%e9%87%8c%e4%b9%9f%e8%84%86%e5%9c%a8%e5%93%aa%e9%87%8c"></a>
二、哈希到底强在哪里（也脆在哪里）
</h2><p>哈希函数的理想目标是：输入再长再乱，我都能稳定给你一个固定长度的“指纹”。而且这个指纹要尽量满足三件事（CTF 和现实都爱考）：</p>
<ol>
<li>
<p><strong>固定长度</strong>：不管你喂它 1 个字符还是 1G 文件，输出长度都固定。</p>
</li>
<li>
<p><strong>雪崩效应</strong>：输入哪怕只改一个字节，输出也会像翻桌一样完全不一样。</p>
</li>
<li>
<p><strong>抗碰撞/抗预像（理想状态）</strong>：</p>
<ul>
<li><strong>碰撞</strong>：找两个不同输入，输出却相同（<code>A != B</code> 但 <code>H(A)=H(B)</code>）。</li>
<li><strong>预像</strong>：给你一个哈希值，让你找到一个输入能产生它（给“指纹”找“手指”）。</li>
</ul>
</li>
</ol>
<p>现实是：算法有“年纪”和“命运”。MD5、SHA-1 都已经不再适合作为安全用途（尤其是防碰撞），但它们在 CTF 里依然很常见——因为题目想考的是<strong>你的识别与流程</strong>，不是真让你写论文。</p>
<p>（SHA 系列的标准可以看 NIST 的 Secure Hash Standard：FIPS 180-4。 (<a href="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf?utm_source=chatgpt.com" title="Secure Hash Standard (SHS) - NIST">NIST出版物</a>)；MD5 的规范可以看 RFC 1321。 (<a href="https://www.rfc-editor.org/rfc/rfc1321?utm_source=chatgpt.com" title="RFC 1321: The MD5 Message-Digest Algorithm">RFC 编辑器</a>)）</p>
        
        <hr><p>本文2025-12-08首发于<a href='http://localhost:1336/'>SWEET'S BLOG</a>，最后修改于2025-12-08</p>]]>
      </description>
      
        <category>ctf-crypto</category>
      
    </item>
    
    

    <item>
      <title>CyberChef：编码基础与可视化解密</title>
      <link>http://localhost:1336/post/%E7%BC%96%E7%A0%81%E5%9F%BA%E7%A1%80%E4%B8%8E%E5%8F%AF%E8%A7%86%E5%8C%96%E8%A7%A3%E5%AF%86/</link>
      <pubDate>Thu, 04 Dec 2025 14:00:00 &#43;0800</pubDate>
      <author>1401617591@qq.com (sweet)</author>
      <guid>http://localhost:1336/post/%E7%BC%96%E7%A0%81%E5%9F%BA%E7%A1%80%E4%B8%8E%E5%8F%AF%E8%A7%86%E5%8C%96%E8%A7%A3%E5%AF%86/</guid>
      <description>
        <![CDATA[<h1>CyberChef：编码基础与可视化解密</h1><p>作者：sweet（1401617591@qq.com）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><p>hello! 欢迎来到咪猫魔法世界 🐾</p>
<p>在 CTF Crypto 里，<strong>编码是“字节与人类语言之间的通用咒语”</strong>：所有明文、密文最终都会以字节（bytes）形式存储与传输。理解编码的标准化规则，就能更快拆解题目外层的数据伪装。
而 <strong>CyberChef</strong> 是咪猫的炼金台：拖拽模块、实时出结果，非常适合用来验证你对“这层到底是不是编码”的判断。</p>
<hr>
<h2 id="一编码-vs-加密">
<a class="header-anchor" href="#%e4%b8%80%e7%bc%96%e7%a0%81-vs-%e5%8a%a0%e5%af%86"></a>
一、编码 vs 加密
</h2><p>编码和加密经常被新手混淆，但它们的目标完全不同。<strong>编码遵循公开的标准规则</strong>，解决的是数据表示与传输问题，所以本身不提供保密性；<strong>加密依赖密钥进行变换</strong>，核心是隐藏内容，没有密钥就难以合法还原。</p>
<table>
  <thead>
      <tr>
          <th>类型</th>
          <th>核心特征</th>
          <th>关键区别</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>编码（Encoding）</td>
          <td>公开标准化规则，解决表示/传输</td>
          <td>无保密性，按规则可还原</td>
      </tr>
      <tr>
          <td>加密（Encryption）</td>
          <td>依赖密钥的变换，隐藏内容</td>
          <td>无密钥难以还原</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p>咪猫口诀：<strong>编码是能读懂，加密是读不懂。</strong></p>
</blockquote>
<blockquote>
<p>小提示：CTF 常把“编码 + 加密”叠加出题，一般顺序是<strong>先解编码，再解加密</strong>。</p>
</blockquote>
<hr>
<h2 id="二ctf-最核心的三类编码">
<a class="header-anchor" href="#%e4%ba%8cctf-%e6%9c%80%e6%a0%b8%e5%bf%83%e7%9a%84%e4%b8%89%e7%b1%bb%e7%bc%96%e7%a0%81"></a>
二、CTF 最核心的三类编码
</h2><h3 id="21-字符编码ascii--utf-8--gbk">
<a class="header-anchor" href="#21-%e5%ad%97%e7%ac%a6%e7%bc%96%e7%a0%81ascii--utf-8--gbk"></a>
2.1 字符编码：ASCII / UTF-8 / GBK
</h3><p>字符编码解决的是<strong>字符与字节之间的标准化映射</strong>，这是所有编码题的地基。ASCII 覆盖英文、数字和基础符号，是很多编码的基础；UTF-8 是互联网主流标准（RFC 3629），兼容 ASCII，多语言场景最常见；GBK 则更常出现在 Windows 环境中，尤其是中文相关的数据。</p>
<p>在 CTF 里我们真正需要记住的不是“背表”，而是一个判断：<strong>同一段字节用错编码会乱码</strong>。例如 GBK 的中文如果按 UTF-8 去解释，就可能出现乱码。遇到这种情况，CyberChef 里用 <code>Decode text</code> 切换编码选项，往往就能直接还原。</p>
<table>
  <thead>
      <tr>
          <th>编码</th>
          <th>权威标准</th>
          <th style="text-align: right">字节占用</th>
          <th>CTF 常见关注点</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>ASCII</td>
          <td>ANSI X3.4-1968</td>
          <td style="text-align: right">1 字节</td>
          <td>基础文本、协议字段</td>
      </tr>
      <tr>
          <td>UTF-8</td>
          <td>RFC 3629</td>
          <td style="text-align: right">1–4 字节</td>
          <td>主流；中文通常 3 字节/字</td>
      </tr>
      <tr>
          <td>GBK</td>
          <td>GB 18030 相关扩展</td>
          <td style="text-align: right">1–2 字节</td>
          <td>Windows 常见；中文通常 2 字节/字</td>
      </tr>
  </tbody>
</table>
<h3 id="22-base-家族base64--base32--base85">
<a class="header-anchor" href="#22-base-%e5%ae%b6%e6%97%8fbase64--base32--base85"></a>
2.2 Base 家族：Base64 / Base32 / Base85
</h3><p>Base 类编码的定位很明确：把二进制数据变成可打印字符，方便在文本通道传输。其中 Base64 与 Base32 可参考 RFC 4648，标准化程度更高。CTF 场景里，Base64 是绝对高频：你会经常遇到“看起来像一串字母数字、末尾带 <code>=</code>”的字符串，它很可能就是 Base64。</p>
        
        <hr><p>本文2025-12-04首发于<a href='http://localhost:1336/'>SWEET'S BLOG</a>，最后修改于2025-12-04</p>]]>
      </description>
      
        <category>ctf-crypto</category>
      
    </item>
    
    

    <item>
      <title>古典密码学入门：置换与替换的核心逻辑</title>
      <link>http://localhost:1336/post/%E5%8F%A4%E5%85%B8%E5%AF%86%E7%A0%81%E7%9A%84%E6%8E%A2%E7%B4%A2/</link>
      <pubDate>Tue, 02 Dec 2025 17:41:26 &#43;0800</pubDate>
      <author>1401617591@qq.com (sweet)</author>
      <guid>http://localhost:1336/post/%E5%8F%A4%E5%85%B8%E5%AF%86%E7%A0%81%E7%9A%84%E6%8E%A2%E7%B4%A2/</guid>
      <description>
        <![CDATA[<h1>古典密码学入门：置换与替换的核心逻辑</h1><p>作者：sweet（1401617591@qq.com）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><p>hello!欢迎来到咪猫魔法世界~</p>
<p>古典密码作为密码学的启蒙积木，虽无现代密码的数学复杂度，却浓缩了置换与替换两大核心思想——这也是现代分组密码、流密码的底层雏形。</p>
<p>在CTF场景中，古典密码常以送分题形式出现，但极易因细节（大小写、字符过滤、密钥格式）翻车。本文将从密码学定义、算法原理、CTF实战解法、工程实现到常见陷阱，全维度拆解栅栏、凯撒、维吉尼亚三类经典古典密码，同时对比Python与C语言实现的工程差异，为后续学习现代密码学筑牢基础。</p>
<hr>
<h2 id="一古典密码的核心分类与设计原则">
<a class="header-anchor" href="#%e4%b8%80%e5%8f%a4%e5%85%b8%e5%af%86%e7%a0%81%e7%9a%84%e6%a0%b8%e5%bf%83%e5%88%86%e7%b1%bb%e4%b8%8e%e8%ae%be%e8%ae%a1%e5%8e%9f%e5%88%99"></a>
一、古典密码的核心分类与设计原则
</h2><p>古典密码的本质是对明文的字符或比特进行可逆变换，核心分为两类（符合Kerckhoffs原则：密码系统的安全性仅依赖密钥，而非算法本身）：</p>
<ul>
<li>置换密码：仅改变字符排列顺序，不修改字符本身（如栅栏、列置换密码）；</li>
<li>替换密码：用新字符替换原字符，保持顺序不变（单表替换：凯撒；多表替换：维吉尼亚）。</li>
</ul>
<p>两类密码的共性：密钥空间有限，易被暴力破解或统计分析攻破——这也是古典密码仅适用于CTF入门，无法满足现代安全需求的核心原因。</p>
<hr>
<h2 id="二置换密码栅栏密码">
<a class="header-anchor" href="#%e4%ba%8c%e7%bd%ae%e6%8d%a2%e5%af%86%e7%a0%81%e6%a0%85%e6%a0%8f%e5%af%86%e7%a0%81"></a>
二、置换密码：栅栏密码
</h2><h3 id="21-密码学定义与核心原理">
<a class="header-anchor" href="#21-%e5%af%86%e7%a0%81%e5%ad%a6%e5%ae%9a%e4%b9%89%e4%b8%8e%e6%a0%b8%e5%bf%83%e5%8e%9f%e7%90%86"></a>
2.1 密码学定义与核心原理
</h3><p>栅栏密码是典型的路由置换密码，核心是将明文按固定轨道数（密钥）以之字形排列，再按轨道顺序拼接得到密文。</p>
<h4 id="核心逻辑">
<a class="header-anchor" href="#%e6%a0%b8%e5%bf%83%e9%80%bb%e8%be%91"></a>
核心逻辑
</h4><p>设明文为一串字符，轨道数为k（密钥），加密过程分为三步：</p>
<ol>
<li>构建k个空轨道（字符数组）；</li>
<li>按向下、向上的折返规则，依次将明文字符填入对应轨道；</li>
<li>按轨道顺序拼接所有字符，得到密文。</li>
</ol>
<h4 id="直观示例明文hellocryptok3">
<a class="header-anchor" href="#%e7%9b%b4%e8%a7%82%e7%a4%ba%e4%be%8b%e6%98%8e%e6%96%87hellocryptok3"></a>
直观示例（明文：HELLOCRYPTO，k=3）
</h4><p>轨道0：H   L   R   T → HLRT
轨道1：E L O C Y P O → ELOCYPO
轨道2：L   C   O     → LCO
密文：HLRTELOCYPOLCO</p>
<h3 id="22-ctf实战解法">
<a class="header-anchor" href="#22-ctf%e5%ae%9e%e6%88%98%e8%a7%a3%e6%b3%95"></a>
2.2 CTF实战解法
</h3><p>栅栏密码在CTF中仅有两种出题形式，解法高度固定：</p>
<table>
  <thead>
      <tr>
          <th>场景</th>
          <th>解法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>已知轨道数k</td>
          <td>直接按轨道折返规则还原明文</td>
      </tr>
      <tr>
          <td>未知轨道数k</td>
          <td>暴力枚举k在2到10之间（超过10无实际加密意义），通过自然语言可读性验证</td>
      </tr>
      <tr>
          <td>变体（列栅栏）</td>
          <td>按列数分组后反转列顺序（如k=2时，每2字符为一组交换位置）</td>
      </tr>
  </tbody>
</table>
<h3 id="23-python实现">
<a class="header-anchor" href="#23-python%e5%ae%9e%e7%8e%b0"></a>
2.3 Python实现
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 栅栏密码核心加解密</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">rail_fence_encrypt</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="n">rails</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">rails</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">text</span>
</span></span><span class="line"><span class="cl">    <span class="n">rows</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;&#39;</span><span class="p">]</span> <span class="o">*</span> <span class="n">rails</span>
</span></span><span class="line"><span class="cl">    <span class="n">r</span><span class="p">,</span> <span class="n">step</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">ch</span> <span class="ow">in</span> <span class="n">text</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">rows</span><span class="p">[</span><span class="n">r</span><span class="p">]</span> <span class="o">+=</span> <span class="n">ch</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">r</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">step</span> <span class="o">=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">        <span class="k">elif</span> <span class="n">r</span> <span class="o">==</span> <span class="n">rails</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">step</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
</span></span><span class="line"><span class="cl">        <span class="n">r</span> <span class="o">+=</span> <span class="n">step</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">rows</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">rail_fence_decrypt</span><span class="p">(</span><span class="n">cipher</span><span class="p">,</span> <span class="n">rails</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">rails</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">cipher</span>
</span></span><span class="line"><span class="cl">    <span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">cipher</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">rail_idx</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">    <span class="n">r</span><span class="p">,</span> <span class="n">step</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">rail_idx</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">r</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">r</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">step</span> <span class="o">=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">        <span class="k">elif</span> <span class="n">r</span> <span class="o">==</span> <span class="n">rails</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">step</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
</span></span><span class="line"><span class="cl">        <span class="n">r</span> <span class="o">+=</span> <span class="n">step</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="n">counts</span> <span class="o">=</span> <span class="p">[</span><span class="n">rail_idx</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">rails</span><span class="p">)]</span>
</span></span><span class="line"><span class="cl">    <span class="n">rails_str</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">    <span class="n">start</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">counts</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">rails_str</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">list</span><span class="p">(</span><span class="n">cipher</span><span class="p">[</span><span class="n">start</span><span class="p">:</span><span class="n">start</span><span class="o">+</span><span class="n">c</span><span class="p">]))</span>
</span></span><span class="line"><span class="cl">        <span class="n">start</span> <span class="o">+=</span> <span class="n">c</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="n">res</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">rid</span> <span class="ow">in</span> <span class="n">rail_idx</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">res</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">rails_str</span><span class="p">[</span><span class="n">rid</span><span class="p">]</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="mi">0</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">res</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 爆破示例</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">rail_fence_brute</span><span class="p">(</span><span class="n">cipher</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">res</span> <span class="o">=</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">k</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">11</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">res</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="n">rail_fence_decrypt</span><span class="p">(</span><span class="n">cipher</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">res</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 测试</span>
</span></span><span class="line"><span class="cl"><span class="n">plain</span> <span class="o">=</span> <span class="s2">&#34;HELLOCRYPTO&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">cipher</span> <span class="o">=</span> <span class="n">rail_fence_encrypt</span><span class="p">(</span><span class="n">plain</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;加密结果：&#34;</span><span class="p">,</span> <span class="n">cipher</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;解密结果：&#34;</span><span class="p">,</span> <span class="n">rail_fence_decrypt</span><span class="p">(</span><span class="n">cipher</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="24-常见陷阱ctf高频翻车点">
<a class="header-anchor" href="#24-%e5%b8%b8%e8%a7%81%e9%99%b7%e9%98%b1ctf%e9%ab%98%e9%a2%91%e7%bf%bb%e8%bd%a6%e7%82%b9"></a>
2.4 常见陷阱（CTF高频翻车点）
</h3><ol>
<li>明文含空格或标点：需确认题目要求保留或过滤（多数题目过滤非字母字符）；</li>
<li>轨道数大于等于明文长度：加密后密文与明文一致，无实际意义；</li>
<li>变体识别：部分题目标注栅栏密码但实际为列置换（需按列数分组反转）。</li>
</ol>
<p>参考资料：<a href="https://blog.csdn.net/Stone__Fly/article/details/53454418">栅栏密码原理与CTF实战</a></p>
        
        <hr><p>本文2025-12-02首发于<a href='http://localhost:1336/'>SWEET'S BLOG</a>，最后修改于2025-12-02</p>]]>
      </description>
      
        <category>ctf-crypto</category>
      
    </item>
    
    

    <item>
      <title>Crypto入门-基于Windows操作系统的环境配置</title>
      <link>http://localhost:1336/post/crypto%E5%85%A5%E9%97%A8--%E5%89%8D%E7%BD%AE%E7%9F%A5%E8%AF%86/</link>
      <pubDate>Sun, 30 Nov 2025 13:37:02 &#43;0800</pubDate>
      <author>1401617591@qq.com (sweet)</author>
      <guid>http://localhost:1336/post/crypto%E5%85%A5%E9%97%A8--%E5%89%8D%E7%BD%AE%E7%9F%A5%E8%AF%86/</guid>
      <description>
        <![CDATA[<h1>Crypto入门-基于Windows操作系统的环境配置</h1><p>作者：sweet（1401617591@qq.com）</p>
        
          <h2 id="引言">
<a class="header-anchor" href="#%e5%bc%95%e8%a8%80"></a>
引言
</h2><p>hello!欢迎来到咪喵魔法世界~</p>
<p>抱着对crypto的强烈好奇与浓烈兴趣，我加入了这个神秘的魔法组织。有句话是这么说的，“当新鲜感褪去，真正的爱才开始浮现”。学习crypto的第四个月，我对这句话的赞同度只增不减。</p>
<p>不得不承认，crypto的学习也许不像第一眼看上去那样“炫酷”，它没有web“改个请求参数就能弹出 flag”的即时快乐；也没有二进制“调通断点让程序跑通”的爽感，学crypto的枯燥是越往深处走越磨人的“顿感枯燥”——不是基础RSA算逆元的机械，是分析复现 Coppersmith 算法攻击时对着 “短私钥多项式构造” 的论文啃一下午，连变量替换的逻辑都没摸透的头昏脑涨；是调 ECC 离散对数题时，对着椭圆曲线的加法法则算到脑仁疼，结果因为曲线参数是弱类型，之前的推演全成了无用功的哭笑不得；是面对无数 Latiice 文献的无从下手，或是左脑子进右脑子出的🤷‍♀️，以至于学到凌晨三更时总有摆烂的念头莫名生出。</p>
<p>然而幸运的是因为学习crypto，我结识了一群志同道合的朋友，认识了愿意带着我们做项目的老师，而我也感谢小小的老己从没想过放弃。</p>
<p>兴趣是指导一个人入门最好的老师，却并不足以支撑他长久的走下去。对我来说，支撑我啃这些枯燥文论的也从来不是 “有趣”，是那种 “慢半拍但沉甸甸” 的成就感；是想拥有一门 “别人替代不了” 的硬技能；是知道学会这些后能有更多的职业选择；甚至是在未来能够设计出一个自己的高安全性的加密程序 —— 这些朴素又真实的动力，比什么 “浪漫的坚持” 都更能让人沉下心，慢慢往前走。</p>
<p>如果你真正沉下心来学习crypto，你就会发现它其实是一门“入门易、精通难”的课程，核心是先把基础框架搭起来，再通过真题慢慢打磨。这篇文章是我整理的 CTF Crypto 前置学习笔记，目标是把「环境搭起来 + 基础语法能上手 + 工具链能跑通」做成一份可复用的操作清单。对于新手小白来说，照着做完，就能在本地拥有一个适合 CTF/Crypto 学习与实验的干净环境啦。</p>
<p>最后再次欢迎大家加入咪猫魔法部~或者一起来见证一只咪猫小cainiao的成长哈哈😄</p>
<hr>
<h2 id="一-环境配置目标以windows系统为例">
<a class="header-anchor" href="#%e4%b8%80-%e7%8e%af%e5%a2%83%e9%85%8d%e7%bd%ae%e7%9b%ae%e6%a0%87%e4%bb%a5windows%e7%b3%bb%e7%bb%9f%e4%b8%ba%e4%be%8b"></a>
一、 环境配置目标（以Windows系统为例）
</h2><p>在 crypto 的世界里，很多“题目做不出来”并不是你不聪明，而是——  <strong>环境没搭好、工具没装对、命令不会用、脚本跑不起来</strong>。</p>
<p>所以这篇文章我们不讲玄学，只讲<strong>把工坊搭好</strong>。不过由于都是最基础的环境配置问题，技术上没什么难点，主要就是跑时间和🖥️，所以我就不一一详细的讲解了，只给出必要的环境配置方向与步骤。（相关下载网址我放在文章最下端了，有需要的可以自取。）</p>
<p>✅ 你最终会拥有：</p>
<ul>
<li>Windows 电脑（主系统）</li>
<li>一个“藏在 Windows 里的 Linux”：WSL2（Ubuntu）</li>
<li>一个不会乱套的 Python 环境：Conda（crypto 专用环境）</li>
<li>一个适合数论/密码学的“超级计算器”：SageMath</li>
<li>一个边算边记边写报告的“魔法笔记本”：Jupyter Notebook</li>
<li>一个能编译 C 代码的工具链：gcc（在 WSL2 里）</li>
</ul>
<p>并且会跑通 2 个最小示例：</p>
<ul>
<li>Python 版凯撒密码 ✅</li>
<li>C 版凯撒密码 ✅</li>
</ul>
<p>如果上述目标你都已经达成了，就可以直接跳过这篇文章进入下一关：RSA / ECC / lattice / 等真题的复现啦。</p>
        
        <hr><p>本文2025-11-30首发于<a href='http://localhost:1336/'>SWEET'S BLOG</a>，最后修改于2025-11-30</p>]]>
      </description>
      
        <category>ctf-crypto</category>
      
    </item>
    
  </channel>
</rss>
