<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>smilin9&#39;s Blog</title>
  
  
  <link href="/atom.xml" rel="self"/>
  
  <link href="http://smilin9.com/"/>
  <updated>2022-12-12T14:57:53.177Z</updated>
  <id>http://smilin9.com/</id>
  
  <author>
    <name>smilin9</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Symmetric Ciphers2</title>
    <link href="http://smilin9.com/2022/06/27/Symmetric%20Ciphers2/"/>
    <id>http://smilin9.com/2022/06/27/Symmetric Ciphers2/</id>
    <published>2022-06-27T06:00:00.000Z</published>
    <updated>2022-12-12T14:57:53.177Z</updated>
    
    <content type="html"><![CDATA[<h1 id="SYMMETRIC-STARTER"><a href="#SYMMETRIC-STARTER" class="headerlink" title="SYMMETRIC STARTER"></a>SYMMETRIC STARTER</h1><h2 id="Modes-of-Operation-Starter"><a href="#Modes-of-Operation-Starter" class="headerlink" title="Modes of Operation Starter"></a>Modes of Operation Starter</h2><h3 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h3><p>The previous set of challenges showed how AES performs a keyed permutation on a block of data. In practice, we need to encrypt messages much longer than a single block. A <em>mode of operation</em> describes how to use a cipher like AES on longer messages.</p><p>All modes have serious weaknesses when used incorrectly. The challenges in this category take you to a different section of the website where you can interact with APIs and exploit those weaknesses. Get yourself acquainted with the interface and use it to take your next flag!</p><p>Play at <a href="http://aes.cryptohack.org/block_cipher_starter">http://aes.cryptohack.org/block_cipher_starter</a></p><h3 id="Analyze"><a href="#Analyze" class="headerlink" title="Analyze"></a>Analyze</h3><p>网站点出去是给了加密方式和过程，一开始以为是要看加密解密函数，但是发现他密文也没给，就很迷。去问了问书记 <code>@chal.route(&#39;/block_cipher_starter/decrypt/&lt;ciphertext&gt;/&#39;)</code> 是啥意思，发现 @ 这个东西表示网页路径，上面这个的网页路径就是 <code>/decrypt/&lt;ciphertext&gt;/</code>， 其中 <ciphertext> 是访问需要的参数，另一个访问不需要参数。就直接请求第二个，得到 <code>encrypt_flag()</code>：</p><figure class="highlight json"><table><tr><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span><span class="attr">&quot;ciphertext&quot;</span><span class="punctuation">:</span><span class="string">&quot;64cede86f533b58fe197a0c9aca6f8d5a7b4389c629cef1c9e90f4e5fe7629a4&quot;</span><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>然后将密文填进解密函数的参数值里面请求得到：</p><figure class="highlight json"><table><tr><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span><span class="attr">&quot;plaintext&quot;</span><span class="punctuation">:</span><span class="string">&quot;63727970746f7b626c30636b5f633170683372355f3472335f663435375f217d&quot;</span><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>明文丢进十六进制解码器得到 flag。</p><h2 id="Passwords-as-Keys"><a href="#Passwords-as-Keys" class="headerlink" title="Passwords as Keys"></a>Passwords as Keys</h2><h3 id="Description-1"><a href="#Description-1" class="headerlink" title="Description"></a>Description</h3><p>It is essential that keys in symmetric-key algorithms are random bytes, instead of passwords or other predictable data. The random bytes should be generated using a cryptographically-secure pseudorandom number generator (CSPRNG). If the keys are predictable in any way, then the security level of the cipher is reduced and it may be possible for an attacker who gets access to the ciphertext to decrypt it.</p><p>Just because a key looks like it is formed of random bytes, does not mean that it necessarily is. In this case the key has been derived from a simple password using a hashing function, which makes the ciphertext crackable.</p><p>For this challenge you may script your HTTP requests to the endpoints, or alternatively attack the ciphertext offline. Good luck!</p><p>Play at <a href="http://aes.cryptohack.org/passwords_as_keys">http://aes.cryptohack.org/passwords_as_keys</a></p><h3 id="Analyze-1"><a href="#Analyze-1" class="headerlink" title="Analyze"></a>Analyze</h3><p>一眼先请求 <code>encrypt_flag()</code>：</p><figure class="highlight json"><table><tr><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span><span class="attr">&quot;ciphertext&quot;</span><span class="punctuation">:</span><span class="string">&quot;c92b7734070205bdf6c0087a751466ec13ae15e6f1bcdd3f3a535ec0f4bbae66&quot;</span><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>把字典保存到本地，读到列表 words 里遍历，将其中的元素依次作为 key，创建 AES 对象 cipher，过滤出以 <code>crypto&#123;</code> 开头的解密文本就是 flag。</p><p>本来是打算爆破然后和密文对比，发现会出好多奇奇怪怪的超时错误，遍历也有问题，9w 多行属实有点离谱。</p><h3 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto.Cipher <span class="keyword">import</span> AES</span><br><span class="line"><span class="keyword">import</span> hashlib</span><br><span class="line"></span><br><span class="line">ciphertext = <span class="built_in">bytes</span>.fromhex(<span class="string">&#x27;c92b7734070205bdf6c0087a751466ec13ae15e6f1bcdd3f3a535ec0f4bbae66&#x27;</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">with</span> <span class="built_in">open</span>(<span class="string">&quot;./1.txt&quot;</span>) <span class="keyword">as</span> f:</span><br><span class="line">    words = [w.strip() <span class="keyword">for</span> w <span class="keyword">in</span> f.readlines()]</span><br><span class="line"><span class="keyword">for</span> w <span class="keyword">in</span> words:</span><br><span class="line">    key = hashlib.md5(w.encode()).digest()</span><br><span class="line">    cipher = AES.new(key, AES.MODE_ECB)</span><br><span class="line">    decoded_text = cipher.decrypt(ciphertext)</span><br><span class="line">    <span class="keyword">if</span> decoded_text.startswith(<span class="string">&#x27;crypto&#123;&#x27;</span>.encode()):</span><br><span class="line">        <span class="built_in">print</span>(decoded_text)</span><br><span class="line">        exit</span><br></pre></td></tr></table></figure><h3 id="SumUp"><a href="#SumUp" class="headerlink" title="SumUp"></a>SumUp</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto.Cipher <span class="keyword">import</span> AES</span><br><span class="line">cipher = AES.new(key, AES.MODE_ECB)</span><br></pre></td></tr></table></figure><h1 id="BLOCK-CIPHERS"><a href="#BLOCK-CIPHERS" class="headerlink" title="BLOCK CIPHERS"></a>BLOCK CIPHERS</h1><h2 id="ECB-CBC-WTF"><a href="#ECB-CBC-WTF" class="headerlink" title="ECB CBC WTF"></a>ECB CBC WTF</h2><h3 id="Description-2"><a href="#Description-2" class="headerlink" title="Description"></a>Description</h3><p>Here you can encrypt in CBC but only decrypt in ECB. That shouldn’t be a weakness because they’re different modes… right?</p><p>Play at <a href="http://aes.cryptohack.org/ecbcbcwtf">http://aes.cryptohack.org/ecbcbcwtf</a></p><h3 id="Analyze-2"><a href="#Analyze-2" class="headerlink" title="Analyze"></a>Analyze</h3><p>第一眼无脑请求 <code>encrypt_flag()</code>，但偶然发现这个东西每次请求到的密文都不一样，顿悟：“喔这是分组密码”。。。</p><p>然后来看图</p><p><img src="https://img.hawa130.com/QQ图片20220723214144.jpg" alt="QQ图片20220723214144"></p><p>获取到的密文长度是 32*3，由代码得出偏移量是前 32 位，把获取到的 ciphertext 分为三组先：</p><figure class="highlight jboss-cli"><table><tr><td class="code"><pre><span class="line">&#123;<span class="string">&quot;ciphertext&quot;</span>:<span class="string">&quot;734aaeb24447ac787dfb0cf09f7c3371246be4c9b9974bf6faad679a36dd42c8e529bb2b2cd1bba8afa460364d5d0ec8&quot;</span>&#125;</span><br><span class="line"></span><br><span class="line">734aaeb24447ac787dfb0cf09f7c3371  <span class="comment">#iv</span></span><br><span class="line">246be4c9b9974bf6faad679a36dd42c8  <span class="comment">#第一组密文</span></span><br><span class="line">e529bb2b2<span class="keyword">cd</span>1bba8afa460364d5d0ec8  <span class="comment">#第二组密文</span></span><br></pre></td></tr></table></figure><p>先解第二组密文，把它填入解密函数的参数位置，得到异或后的密文 </p><figure class="highlight json"><table><tr><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span><span class="attr">&quot;plaintext&quot;</span><span class="punctuation">:</span><span class="string">&quot;7b5f92f988f314c7cdf246bb17fc63b5&quot;</span><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>这是第二组明文和第一组密文异或的结果，由于第一组密文已知，所以直接和它进行异或得到第二组明文 </p><figure class="highlight"><table><tr><td class="code"><pre><span class="line">5f34763031645f31375f21212121217d</span><br></pre></td></tr></table></figure><p>同理，第一组密文解密之后得到 </p><figure class="highlight json"><table><tr><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span><span class="attr">&quot;plaintext&quot;</span><span class="punctuation">:</span><span class="string">&quot;1038d7c23028d74b1e9953c5ea1f5844&quot;</span><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>将其与偏移量进行异或得到第一组明文 </p><figure class="highlight dns"><table><tr><td class="code"><pre><span class="line"><span class="number">63727970746</span>f7b3363625f<span class="number">3575636b35</span></span><br></pre></td></tr></table></figure><p>拼接得到明文为</p><figure class="highlight"><table><tr><td class="code"><pre><span class="line">63727970746f7b3363625f3575636b355f34763031645f31375f21212121217d</span><br></pre></td></tr></table></figure><p>hex 解码之后得到 flag。</p><h2 id="ECB-Oracle"><a href="#ECB-Oracle" class="headerlink" title="ECB Oracle"></a>ECB Oracle</h2><h3 id="Description-3"><a href="#Description-3" class="headerlink" title="Description"></a>Description</h3><p>ECB is the most simple mode, with each plaintext block encrypted entirely independently. In this case, your input is prepended to the secret flag and encrypted and that’s it. We don’t even provide a decrypt function. Perhaps you don’t need a padding oracle when you have an “ECB oracle”?</p><p>Play at <a href="http://aes.cryptohack.org/ecb_oracle">http://aes.cryptohack.org/ecb_oracle</a></p><h3 id="Analyze-3"><a href="#Analyze-3" class="headerlink" title="Analyze"></a>Analyze</h3><h3 id="Code-1"><a href="#Code-1" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure><h3 id="SumUp-1"><a href="#SumUp-1" class="headerlink" title="SumUp"></a>SumUp</h3><h2 id="Flipping-Cookie"><a href="#Flipping-Cookie" class="headerlink" title="Flipping Cookie"></a>Flipping Cookie</h2><h3 id="Description-4"><a href="#Description-4" class="headerlink" title="Description"></a>Description</h3><h3 id="Analyze-4"><a href="#Analyze-4" class="headerlink" title="Analyze"></a>Analyze</h3><h3 id="Code-2"><a href="#Code-2" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto.Cipher <span class="keyword">import</span> AES</span><br><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> json</span><br><span class="line"><span class="keyword">import</span> copy</span><br><span class="line"></span><br><span class="line">r = requests.get(<span class="string">&#x27;http://aes.cryptohack.org/flipping_cookie/get_cookie/&#x27;</span>)</span><br><span class="line">cookie_payload = json.loads(r.text)[<span class="string">&quot;cookie&quot;</span>]</span><br><span class="line"></span><br><span class="line">iv = cookie_payload[:<span class="number">32</span>]</span><br><span class="line">cookie = cookie_payload[<span class="number">32</span>:]</span><br><span class="line"></span><br><span class="line">iv_new = copy.deepcopy(iv)</span><br><span class="line">xor_value = (<span class="number">0x12</span> &lt;&lt; <span class="number">72</span> | <span class="number">0x13</span> &lt;&lt; <span class="number">64</span> | <span class="number">0x19</span> &lt;&lt; <span class="number">56</span> | <span class="number">0x16</span> &lt;&lt; <span class="number">48</span> | <span class="number">0x5e</span> &lt;&lt; <span class="number">40</span>) &amp; ((<span class="number">0xFFFFFFFFFF</span> &lt;&lt; <span class="number">88</span>) &gt;&gt; <span class="number">48</span>)</span><br><span class="line"></span><br><span class="line">iv_new = <span class="built_in">int</span>(iv_new, <span class="number">16</span>) ^ xor_value </span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">hex</span>(iv_new))</span><br><span class="line"></span><br><span class="line">get_param = <span class="string">&#x27;http://aes.cryptohack.org/flipping_cookie/check_admin/&#x27;</span> + cookie + <span class="string">&#x27;/&#x27;</span> + <span class="built_in">str</span>(<span class="built_in">hex</span>(iv_new))[<span class="number">2</span>:] + <span class="string">&#x27;/&#x27;</span></span><br><span class="line">r2 = requests.get(get_param)</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(r2.text)</span><br></pre></td></tr></table></figure><h3 id="SumUp-2"><a href="#SumUp-2" class="headerlink" title="SumUp"></a>SumUp</h3><h2 id="Lazy-CBC"><a href="#Lazy-CBC" class="headerlink" title="Lazy CBC"></a>Lazy CBC</h2><h3 id="Description-5"><a href="#Description-5" class="headerlink" title="Description"></a>Description</h3><h3 id="Analyze-5"><a href="#Analyze-5" class="headerlink" title="Analyze"></a>Analyze</h3><h3 id="Code-3"><a href="#Code-3" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure><h3 id="SumUp-3"><a href="#SumUp-3" class="headerlink" title="SumUp"></a>SumUp</h3><h2 id="Triple-DES"><a href="#Triple-DES" class="headerlink" title="Triple DES"></a>Triple DES</h2><h3 id="Description-6"><a href="#Description-6" class="headerlink" title="Description"></a>Description</h3><h3 id="Analyze-6"><a href="#Analyze-6" class="headerlink" title="Analyze"></a>Analyze</h3><h3 id="Code-4"><a href="#Code-4" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure><h3 id="SumUp-4"><a href="#SumUp-4" class="headerlink" title="SumUp"></a>SumUp</h3>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h1 id=&quot;SYMMETRIC-STARTER&quot;&gt;&lt;a href=&quot;#SYMMETRIC-STARTER&quot; class=&quot;headerlink&quot; title=&quot;SYMMETRIC STARTER&quot;&gt;&lt;/a&gt;SYMMETRIC STARTER&lt;/h1&gt;&lt;h2 id=&quot;Modes
      
    
    </summary>
    
      <category term="学习" scheme="http://smilin9.com/categories/%E5%AD%A6%E4%B9%A0/"/>
    
    
      <category term="cryptohack" scheme="http://smilin9.com/tags/cryptohack/"/>
    
  </entry>
  
  <entry>
    <title>数据库复习</title>
    <link href="http://smilin9.com/2022/06/18/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%A4%8D%E4%B9%A0/"/>
    <id>http://smilin9.com/2022/06/18/数据库复习/</id>
    <published>2022-06-18T16:00:00.000Z</published>
    <updated>2022-12-12T14:57:53.177Z</updated>
    
    <content type="html"><![CDATA[<h2 id="题型"><a href="#题型" class="headerlink" title="题型"></a>题型</h2><p>单选：10 个 × 2 分</p><p>填空：10 个 × 1 分</p><p>综合应用题：3 个，每个 10-30 分（考察 2-6 章知识点，重点为关系代数和 sql 语句）</p><h2 id="第一章-数据库系统概述"><a href="#第一章-数据库系统概述" class="headerlink" title="第一章 数据库系统概述"></a>第一章 数据库系统概述</h2><ol><li>数据库的 4 个基本概念<ul><li>数据</li><li>数据库</li><li>数据库系统 = 数据库 + 数据库管理系统 + 应用程序 + 数据库管理员</li><li>数据库管理系统：本质是软件</li></ul></li></ol><h2 id="第二章-关系数据库"><a href="#第二章-关系数据库" class="headerlink" title="第二章 关系数据库"></a>第二章 关系数据库</h2><h3 id="关系数据结构及形式化定义"><a href="#关系数据结构及形式化定义" class="headerlink" title="关系数据结构及形式化定义"></a>关系数据结构及形式化定义</h3><ol><li>域：概念上等同于集合</li><li>笛卡尔积：几个集合取乘积（类似于乘法分配律）所得的集合，不能有重复元素</li><li>基数：一个域中的不同元素的个数叫做域的基数</li><li>关系：若干个域的笛卡尔积的子集叫做域上的关系，写为 $R(D_1,D_2,\ldots ,D_n)$，其中 n 叫做关系的目或者度</li><li>候选码：关系中某一属性组能唯一标识一个元组，而其子集不能，这个属性组叫做候选码。（不能有重复的取值）</li><li>主码：一个关系有多个候选码时，选定其中一个为主码。候选码的诸属性叫主属性</li><li>关系的三种类型：基本关系（基本表），查询表，视图表</li><li>表中不能有小表</li><li>关系模式：$R(U,D,DOM)$</li></ol><h3 id="关系操作"><a href="#关系操作" class="headerlink" title="关系操作"></a>关系操作</h3><ol><li>基本的关系操作：<ul><li>查询（前五种为五种基本操作）<ul><li>选择</li><li>投影</li><li>并</li><li>差</li><li>笛卡尔积</li><li>连接</li><li>除</li><li>交</li></ul></li><li>插入、删除、修改</li></ul></li></ol><h3 id="关系的完整性"><a href="#关系的完整性" class="headerlink" title="关系的完整性"></a>关系的完整性</h3><ol><li>实体完整性：主属性不能取空值</li><li>参照完整性：<ul><li>F 是关系 R 的属性但不是码，K 是关系 S 的主码，如果 F 和 K 相对应，则 F 是关系 R 的外码，称 R 是参照关系，S 是被参照关系。R、S 可以是同一关系。</li><li>F 是关系 R 的外码，则 F 的各个取值或者取空值，或者等于 S 中对应的值</li></ul></li><li>用户定义的完整性</li></ol><h3 id="关系代数"><a href="#关系代数" class="headerlink" title="关系代数"></a>关系代数</h3><ol><li><p>用对关系的运算表达查询</p></li><li><p>传统的集合运算</p><ul><li>并 $R \cup S$，两集合取并集</li><li>差  $R - S$，属于 R 但不属于 S</li><li>交 $R \cap S$，两集合取交集</li><li>笛卡尔积 $R \times S$</li></ul></li><li><p>专门的关系运算</p><ul><li><p>选择（限制）：在关系R中选择满足给定条件的诸元组，$\sigma <em>F(R)$（例如，$\sigma </em>{Sdept=’IS’}(student)$），其中F表示选择条件。是从行的角度进行的运算。</p></li><li><p>投影：从关系R中选择出若干属性列组成新的关系，$\pi<em>A(R)$（例如，$\pi</em>{Sname}(student)$），其中 A 是 R 的属性列，结果应取消相同行。是从列的角度进行运算。</p></li><li><p>连接：从两个关系的笛卡尔积里选择满足关系的元组，$R \underset{A\theta B}\Join S$，其中 $\theta$ 为比较运算符。</p><ul><li>等值连接：当 $\theta$ 为 ”$=$“ 时<ul><li>自然连接：特殊的等值连接，进行比较的分量必须是同名的属性组，并在结果中取消重复列。同时从行和列的角度进行运算。</li></ul></li><li>外连接<ul><li>悬浮元组：自然连接运算中被舍弃的元组</li><li>外连接：把悬浮元组也保存在结果关系中，在其他属性填 $NULL$，$R\ ⟗\ S$<ul><li>左外连接：只保留左边关系 R 的悬浮元组，$R\ ⟕\ S$</li><li>右外连接：只保留左边关系 S 的悬浮元组，$R\ ⟖\ S$</li></ul></li></ul></li></ul></li><li><p>除：$R\div S=T$，$T$ 包含在 R 但不在 S 中的属性及其值。同时从行和列的角度进行运算。</p><p>类似于在两关系的共同属性上一一对照，找到左边关系中含右边关系的所有非共同属性的非共同属性，即为运算结果。</p></li></ul></li></ol><h2 id="第三章-关系数据库标准语言-SQL"><a href="#第三章-关系数据库标准语言-SQL" class="headerlink" title="第三章 关系数据库标准语言 SQL"></a>第三章 关系数据库标准语言 SQL</h2><h3 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h3><ol><li>SQL 的特点<ul><li>综合统一<ul><li>SQL 集数据定义语言、数据操纵语言、数据控制语言、数据查询语言的功能于一体</li></ul></li><li>高度非过程化</li><li>面向集合的操作方式</li><li>提供多种使用方式</li><li>语言简洁，易学易用</li></ul></li></ol><h3 id="数据定义"><a href="#数据定义" class="headerlink" title="数据定义"></a>数据定义</h3><ol><li><p>模式</p><ul><li><p>定义</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">create</span> schema <span class="operator">&lt;</span>模式名<span class="operator">&gt;</span> <span class="keyword">authorization</span> <span class="operator">&lt;</span>用户名<span class="operator">&gt;</span></span><br></pre></td></tr></table></figure><p><img src="https://img.hawa130.com/image-20220621145809959.png" alt="image-20220621145809959"></p></li><li><p>删除</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">drop</span> schema <span class="operator">&lt;</span>模式名<span class="operator">&gt;</span><span class="operator">&lt;</span>cascade（级联）<span class="operator">|</span>restrict（限制）<span class="operator">&gt;</span></span><br></pre></td></tr></table></figure><p>级联和限制必选其一，级联表示把该模式的数据库对象全部删除；限制表示如果已经该模式中如果已经定义了下属的数据库对象，就拒绝该语句的执行。</p><p><img src="https://img.hawa130.com/image-20220621145833629.png" alt="image-20220621145833629"></p></li><li><p>常用完整性约束</p><p><img src="https://img.hawa130.com/image-20220621150948118.png" alt="image-20220621150948118"></p></li></ul></li><li><p>基本表</p><p><img src="https://img.hawa130.com/image-20220621145727498.png" alt="image-20220621145727498"></p><ul><li><p>定义表</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> <span class="operator">&lt;</span>表名<span class="operator">&gt;</span>(</span><br><span class="line"><span class="operator">&lt;</span>列名<span class="operator">&gt;</span><span class="operator">&lt;</span>数据类型<span class="operator">&gt;</span> [列级完整约束条件]</span><br><span class="line">    [，<span class="operator">&lt;</span>表级完整约束条件<span class="operator">&gt;</span>]);</span><br></pre></td></tr></table></figure></li><li><p>删除表</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">drop</span> <span class="keyword">table</span> <span class="operator">&lt;</span>表名<span class="operator">&gt;</span> [restrict<span class="operator">|</span>cascade]; </span><br></pre></td></tr></table></figure><ul><li>restrict：删除表有限制条件。欲删除的基本表不能被其他表的约束所引用，如果存在依赖该表的对象，则此表不能被删除。 默认是 restrict。</li><li>cascade：删除表没有限制条件。在删除基本表的同时，相关的依赖对象一起删除 </li></ul><p><img src="https://img.hawa130.com/image-20220621152410203.png" alt="image-20220621152410203"></p></li><li><p>模式与表</p><ul><li><p>表中给出模式名</p><p><img src="https://img.hawa130.com/image-20220621150534682.png" alt="image-20220621150534682"></p></li><li><p>创建模式语句中同时创建表</p><p><img src="https://img.hawa130.com/image-20220621150618987.png" alt="image-20220621150618987"></p></li></ul></li><li><p>修改表</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">alter</span> <span class="keyword">table</span> <span class="operator">&lt;</span>表名<span class="operator">&gt;</span> </span><br><span class="line">[<span class="keyword">add</span> <span class="operator">&lt;</span>新列名<span class="operator">&gt;</span> <span class="operator">&lt;</span>数据类型<span class="operator">&gt;</span> [完整性约束]] </span><br><span class="line">[<span class="keyword">drop</span> <span class="operator">&lt;</span>完整性约束名<span class="operator">&gt;</span>] </span><br><span class="line">[<span class="keyword">alter</span> <span class="keyword">column</span> <span class="operator">&lt;</span>列名<span class="operator">&gt;</span> type <span class="operator">&lt;</span>数据类]; </span><br></pre></td></tr></table></figure><p><img src="https://img.hawa130.com/image-20220621152230609.png" alt="image-20220621152230609"></p></li><li><p>表级完整性约束条件定义</p><p><img src="https://img.hawa130.com/image-20220621151833405.png" alt="image-20220621151833405"></p></li></ul></li><li><p>索引</p><ul><li><p>分类</p><ul><li>普通索引(normal Index)：索引表的 Search-key 项中的每一索引值对应全部取该值的基本表中的记录。普通索引通过索引表的指针项指向一个单链表来实现，该链表的每个结点的数据项指向一条物理记录。 </li><li>单一索引(unique Index)：每一个索引值只对应唯一的数据记录。当建立单一索引后，索引项不可以再插入已有值，但可以插入多个空值，这等同于在建表时对索引列增加一个 UNIQUE 约束；同样，当建立单一索引时，如果待索引项存在相同值则不能建立。 </li><li>聚簇索引(cluster Index)：索引项顺序与表中数据记录的物理顺序一致。即基本表是按照索引表的 Search-key 项的排列次序组织存储的，因此，一个基本表只能建立一个聚簇索引。</li></ul></li><li><p>建立索引</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">create</span> [<span class="keyword">unique</span>] <span class="operator">|</span> [cluster] index <span class="operator">&lt;</span>索引名<span class="operator">&gt;</span></span><br><span class="line"><span class="keyword">on</span> <span class="operator">&lt;</span>表名<span class="operator">&gt;</span>(<span class="operator">&lt;</span>列名<span class="operator">&gt;</span>[<span class="operator">&lt;</span>次序<span class="operator">&gt;</span>][,<span class="operator">&lt;</span>列名<span class="operator">&gt;</span>[<span class="operator">&lt;</span>次序<span class="operator">&gt;</span>] ]…) ;</span><br></pre></td></tr></table></figure><ul><li><p>用表名指定要建索引的基本表名字</p></li><li><p>索引可以建立在该表的一列或多列上，各列名之间用逗号分隔</p></li><li><p>用次序指定索引值的排列次序，升序：ASC，降序：DESC；缺省值：ASC</p></li><li><p>unique 表明此索引的每一个索引值对应唯一的数据记录</p></li><li><p>cluster 表示要建立的索引是聚簇索引</p></li></ul></li></ul></li></ol><p>  <img src="https://img.hawa130.com/image-20220621153010553.png" alt="image-20220621153010553"></p><ul><li><p>删除索引</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">alter</span> <span class="keyword">table</span> <span class="operator">&lt;</span>表名<span class="operator">&gt;</span> <span class="keyword">drop</span> index <span class="operator">&lt;</span>索引名<span class="operator">&gt;</span>;</span><br></pre></td></tr></table></figure><p><img src="https://img.hawa130.com/image-20220621153246594.png" alt="image-20220621153246594"></p></li></ul><h3 id="数据查询"><a href="#数据查询" class="headerlink" title="数据查询"></a>数据查询</h3><ol><li><p>单表查询</p><ul><li><p>select 语句</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">SELECT</span> [<span class="keyword">ALL</span> <span class="operator">|</span> <span class="keyword">DISTINCT</span>] <span class="operator">&lt;</span>目标列表达式<span class="operator">&gt;</span> [,<span class="operator">&lt;</span>目标列表达式<span class="operator">&gt;</span>] … </span><br><span class="line"><span class="keyword">FROM</span> <span class="operator">&lt;</span>表名或视图名<span class="operator">&gt;</span>[, <span class="operator">&lt;</span>表名或视图名<span class="operator">&gt;</span> ] … </span><br><span class="line">[ <span class="keyword">WHERE</span> <span class="operator">&lt;</span>条件表达式<span class="operator">&gt;</span> ] </span><br><span class="line">[ <span class="keyword">GROUP</span> <span class="keyword">BY</span> <span class="operator">&lt;</span>列名<span class="number">1</span><span class="operator">&gt;</span> [ <span class="keyword">HAVING</span> <span class="operator">&lt;</span>条件表达式<span class="operator">&gt;</span> ] ] </span><br><span class="line">[ <span class="keyword">ORDER</span> <span class="keyword">BY</span> <span class="operator">&lt;</span>列名<span class="number">2</span><span class="operator">&gt;</span> [ <span class="keyword">ASC</span> <span class="operator">|</span> <span class="keyword">DESC</span> ] ] ;</span><br></pre></td></tr></table></figure><ul><li>select 子句：指定要显示的属性列</li><li>from 子句：指定查询对象(基本表或视图)</li><li>where 子句：指定查询条件</li><li>group by 子句：对查询结果按指定列的值分组，该属性列值相等的元组为一个组。通常会在每组中使用集函数；having 短语：筛选出只有满足指定条件的组</li><li>order by 子句：对查询结果按指定列值升序或降序排序</li></ul></li><li><p>选择表中的若干列（$\pi$）</p><p><img src="https://img.hawa130.com/image-20220621154928698.png" alt="image-20220621154928698"></p></li><li><p>查询指定列</p></li><li><p>查询全部列</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">select</span> <span class="operator">*</span></span><br><span class="line"><span class="keyword">from</span> <span class="operator">&lt;</span><span class="keyword">table</span><span class="operator">&gt;</span>;</span><br></pre></td></tr></table></figure></li><li><p>查询经过计算的值</p><p><img src="https://img.hawa130.com/image-20220621155135450.png" alt="image-20220621155135450"></p></li><li><p>选择表中的若干元组</p></li><li><p>消除取值重复的行：distinct</p><p><img src="https://img.hawa130.com/image-20220621155247785.png" alt="image-20220621155247785"></p></li><li><p>查询满足条件的元组：where（$\sigma$）</p><ul><li><p>比较</p><p><img src="https://img.hawa130.com/image-20220621155641853.png" alt="image-20220621155641853"></p></li><li><p>确定范围：between and，not between and</p><p><img src="https://img.hawa130.com/image-20220621155816131.png" alt="image-20220621155816131"></p></li><li><p>确定集合：in，not in</p><p><img src="https://img.hawa130.com/image-20220621155833237.png" alt="image-20220621155833237"></p></li><li><p>字符匹配：like，not like</p><ul><li>%：任意长度字符串</li><li>_：任意单个字符</li></ul><p><img src="https://img.hawa130.com/image-20220621155947142.png" alt="image-20220621155947142"></p></li><li><p>涉及空值的查询：is nullI，is not null</p><p><img src="https://img.hawa130.com/image-20220621160118928.png" alt="image-20220621160118928"></p></li><li><p>多重条件（逻辑运算）：and，or，not</p><p><img src="https://img.hawa130.com/image-20220621160240283.png" alt="image-20220621160240283"></p></li></ul></li><li><p>order by 语句</p><ul><li>可以按一个或多个属性列排序<ul><li>升序：ASC</li><li>降序：DESC</li><li>默认为升序 </li></ul></li><li>当排序列含空值时：将空值作为最大值来理解</li></ul><p><img src="https://img.hawa130.com/image-20220621160610847.png" alt="image-20220621160610847"></p></li><li><p>聚集函数（count，sum，avg，max，min：只能用于 SELECT 语句和 GROUP BY</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line">计数</span><br><span class="line"><span class="built_in">COUNT</span> ([<span class="keyword">DISTINCT</span><span class="operator">|</span><span class="keyword">ALL</span>] <span class="operator">*</span>) <span class="built_in">COUNT</span> ([<span class="keyword">DISTINCT</span><span class="operator">|</span><span class="keyword">ALL</span>] <span class="operator">&lt;</span>列名<span class="operator">&gt;</span>)</span><br><span class="line">计算总和</span><br><span class="line"><span class="built_in">SUM</span> ([<span class="keyword">DISTINCT</span><span class="operator">|</span><span class="keyword">ALL</span>] <span class="operator">&lt;</span>列名<span class="operator">&gt;</span>)</span><br><span class="line">计算平均值</span><br><span class="line"><span class="built_in">AVG</span> ([<span class="keyword">DISTINCT</span><span class="operator">|</span><span class="keyword">ALL</span>] <span class="operator">&lt;</span>列名<span class="operator">&gt;</span>)</span><br><span class="line">求最大值</span><br><span class="line"><span class="built_in">MAX</span> ([<span class="keyword">DISTINCT</span><span class="operator">|</span><span class="keyword">ALL</span>] <span class="operator">&lt;</span>列名<span class="operator">&gt;</span>)</span><br><span class="line">求最小值</span><br><span class="line"><span class="built_in">MIN</span> ([<span class="keyword">DISTINCT</span><span class="operator">|</span><span class="keyword">ALL</span>] <span class="operator">&lt;</span>列名<span class="operator">&gt;</span>)</span><br></pre></td></tr></table></figure><p><img src="https://img.hawa130.com/image-20220621160911225.png" alt="image-20220621160911225"></p></li><li><p>GROUP BY 语句</p><p><img src="https://img.hawa130.com/image-20220621161034237.png" alt="image-20220621161034237"></p></li></ul></li><li><p>连接查询</p><ul><li><p>等值与非等值连接查询</p><p><img src="https://img.hawa130.com/image-20220621162218418.png" alt="image-20220621162218418"></p><ul><li>自然连接：等值连接中，去掉重复的属性列为自然连接</li></ul></li><li><p>自身连接</p><p><img src="https://img.hawa130.com/image-20220621162311919.png" alt="image-20220621162311919"></p></li><li><p>外连接</p><ul><li>左外连接列出左边关系所有元组</li><li>右外连接列出右边关系所有元组</li></ul><p><img src="https://img.hawa130.com/image-20220621162342054.png" alt="image-20220621162342054"></p></li><li><p>多表连接</p><p><img src="https://img.hawa130.com/image-20220621162506142.png" alt="image-20220621162506142"></p></li></ul></li><li><p>嵌套查询</p><ul><li><p>查询块：一个 select-from-where 语句称为一个查询块 </p></li><li><p>带有 IN 谓词的子查询</p><ul><li>不相关子查询：子查询的查询条件不依赖于父查询（可以用自身连接）</li><li>相关子查询：子查询的查询条件依赖于父查询</li></ul><p><img src="https://img.hawa130.com/image-20220621162804315.png" alt="image-20220621162804315"></p><p><img src="https://img.hawa130.com/image-20220621162858568.png" alt="image-20220621162858568"></p></li><li><p>带有比较运算符的子查询（比较运算符）</p><p><img src="https://img.hawa130.com/image-20220621162936356.png" alt="image-20220621162936356"></p></li><li><p>带有 ANY（SOME）或 ALL 谓词的子查询（效率低于聚集函数）</p><p><img src="https://img.hawa130.com/image-20220621165645842.png" alt="image-20220621165645842"></p></li><li><p>带有 EXISTS 谓词的子查询，不返回任何值，只产生逻辑真，假</p><p><img src="https://img.hawa130.com/image-20220621165920051.png" alt="image-20220621165920051"></p><p><img src="https://img.hawa130.com/image-20220621170225381.png" alt="image-20220621170225381"></p></li></ul></li><li><p>集合查询</p><ul><li>并 union：将多个查询结果合并，自动去掉重复元组</li><li>交 intersect</li><li>差 except</li></ul><p><img src="https://img.hawa130.com/image-20220621170350062.png" alt="image-20220621170350062"></p></li><li><p>基于派生表的查询</p></li></ol><h3 id="数据更新"><a href="#数据更新" class="headerlink" title="数据更新"></a>数据更新</h3><ol><li><p>插入数据</p><ul><li><p>插入元组 INSERT INTO VALUES</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> <span class="operator">&lt;</span>表名<span class="operator">&gt;</span> [(<span class="operator">&lt;</span>属性列<span class="number">1</span><span class="operator">&gt;</span>[，<span class="operator">&lt;</span>属性列<span class="number">2</span> <span class="operator">&gt;</span>…)] </span><br><span class="line"><span class="keyword">VALUES</span> (<span class="operator">&lt;</span>常量<span class="number">1</span><span class="operator">&gt;</span> [，<span class="operator">&lt;</span>常量<span class="number">2</span><span class="operator">&gt;</span>] … ) ;</span><br></pre></td></tr></table></figure><ul><li>INTO 子句 <ul><li>指定要插入数据的表名及属性列 </li><li>属性列的顺序可与表定义中的顺序不一致 </li><li>没有指定属性列：表示要插入的是一条完整的元组，且属性列属性与表定义中的顺序一致 </li><li>指定部分属性列：插入的元组在其余属性列上取空值 </li></ul></li><li>VALUES 子句：提供的值的个数和值的类型必须与 INTO 子句匹配</li></ul><p><img src="https://img.hawa130.com/image-20220621170659802.png" alt="image-20220621170659802"></p></li><li><p>插入子查询结果 INSERT INTO 子查询</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">INSERT</span> <span class="keyword">INTO</span> <span class="operator">&lt;</span>表名<span class="operator">&gt;</span> [(<span class="operator">&lt;</span>属性列<span class="number">1</span><span class="operator">&gt;</span> [，<span class="operator">&lt;</span>属性列<span class="number">2</span><span class="operator">&gt;</span>… )]</span><br><span class="line">子查询；</span><br></pre></td></tr></table></figure><ul><li>INTO 子句，与插入单条元组类似</li><li>子查询，SELECT 子句目标列属性的个数和类型必须与 INTO 子句匹配。</li></ul></li></ul></li><li><p>修改数据 UPDATE SET</p><ul><li><p>语法</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">UPDATE</span> <span class="operator">&lt;</span>表名<span class="operator">&gt;</span></span><br><span class="line"><span class="keyword">SET</span> <span class="operator">&lt;</span>列名<span class="operator">&gt;=</span><span class="operator">&lt;</span>表达式<span class="operator">&gt;</span>[, <span class="operator">&lt;</span>列名<span class="operator">&gt;=</span><span class="operator">&lt;</span>表达式<span class="operator">&gt;</span>]…</span><br><span class="line">[<span class="keyword">WHERE</span> <span class="operator">&lt;</span>条件<span class="operator">&gt;</span>]；</span><br></pre></td></tr></table></figure><ul><li><p>SET 子句：指定修改方式，要修改的列和修改后取值 </p></li><li><p>WHERE 子句</p><ul><li>指定要修改的元组 </li><li>缺省表示要修改表中的所有元组</li></ul></li></ul></li><li><p>修改某一个元组的值</p><p><img src="https://img.hawa130.com/image-20220621171031249.png" alt="image-20220621171031249"></p></li><li><p>修改多个元组的值</p><p><img src="https://img.hawa130.com/image-20220621171041685.png" alt="image-20220621171041685"></p></li><li><p>带子查询的修改语句</p><p><img src="https://img.hawa130.com/image-20220621171059422.png" alt="image-20220621171059422"></p></li></ul></li><li><p>删除数据（DELETE 只删除表的数据，不删除表的定义）</p><ul><li><p>语法</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">DELETE</span> <span class="keyword">FROM</span> <span class="operator">&lt;</span>表名<span class="operator">&gt;</span> </span><br><span class="line">[<span class="keyword">WHERE</span> <span class="operator">&lt;</span>条件<span class="operator">&gt;</span>] ;</span><br></pre></td></tr></table></figure><ul><li>WHERE 子句<ul><li>指定要删除的元组</li><li>缺省表示要修改表中的所有元组</li></ul></li></ul></li><li><p>删除某一个元组的值</p><p><img src="https://img.hawa130.com/image-20220621171224247.png" alt="image-20220621171224247"></p></li><li><p>删除多个元组的值</p><p><img src="https://img.hawa130.com/image-20220621171233737.png" alt="image-20220621171233737"></p></li><li><p>带子查询的删除语句</p><p><img src="https://img.hawa130.com/image-20220621171244026.png" alt="image-20220621171244026"></p></li></ul></li></ol><h3 id="空值的处理"><a href="#空值的处理" class="headerlink" title="空值的处理"></a>空值的处理</h3><ol><li><p>空值的判断：is null，is not null</p><p><img src="https://img.hawa130.com/image-20220621171342883.png" alt="image-20220621171342883"></p></li><li><p>空值的约束条件</p><ul><li>有 NOT NULL 约束条件的不能取空值</li><li>加了 UNIQUE 限制的属性不能取空值</li><li>码属性不能取空值</li></ul></li><li><p>空值的运算</p><ul><li>算术运算：空值与另一个值（包括另一个空值）的算术运算的结果为空值</li><li>比较运算：空值与另一个值（包括另一个空值）的比较运算的结果为 UNKNOWN</li><li>逻辑运算：有 UNKNOWN 后，传统二值（TRUE，FALSE）逻辑就扩展成了三值逻辑</li></ul></li></ol><h3 id="视图"><a href="#视图" class="headerlink" title="视图"></a>视图</h3><ol><li><p>是一个虚表</p></li><li><p>对应三级模式的外模式</p></li><li><p>定义视图</p><ul><li><p>建立视图</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">CREATE</span> <span class="keyword">VIEW</span> <span class="operator">&lt;</span>视图名<span class="operator">&gt;</span> [(<span class="operator">&lt;</span>列名<span class="operator">&gt;</span> [，<span class="operator">&lt;</span>列名<span class="operator">&gt;</span>]…)] </span><br><span class="line"><span class="keyword">AS</span> <span class="operator">&lt;</span>子查询<span class="operator">&gt;</span> </span><br><span class="line">[<span class="keyword">WITH</span> <span class="keyword">CHECK</span> OPTION]；</span><br></pre></td></tr></table></figure><ul><li>CREATE VIEW 子句中的列名可以省略，此时视图的属性由子查询中 SELECT 目标列中的诸字段组成。但在下列情况下明确指定视图的所有列名：<ul><li>某个目标列是集函数或列表达式</li><li>多表连接时选出了几个同名列作为视图的字段 </li><li>需要在视图中为某个列启用新的更合适的名字 </li></ul></li><li>子查询中的属性列不允许定义别名，不允许含有 ORDER BY 子句和 DISTINCT 短语。 </li><li>WITH CHECK OPTION 表示对视图进行更新操作的数据必须满足视图定义的谓词条件(子查询的条件表达式)。</li></ul><p><img src="https://img.hawa130.com/image-20220621172346205.png" alt="image-20220621172346205"></p><p><img src="https://img.hawa130.com/image-20220621172712431.png" alt="image-20220621172712431"></p></li><li><p>删除视图</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">DROP</span> <span class="keyword">VIEW</span> <span class="operator">&lt;</span>视图名<span class="operator">&gt;</span> [CASCADE] ;</span><br></pre></td></tr></table></figure></li></ul></li></ol><ol><li><p>查询视图</p><ul><li><p>和基本表一样</p><ul><li>如果该视图导出了其他视图，则使用CASCADE级联删除，或者先显式删除导出的视图，再删除该视图； </li><li>删除基表时，由该基表导出的所有视图定义都必须显式删除。</li></ul></li><li><p>DBMS 实现视图查询的方法</p><ul><li><p>实体化视图</p><p><img src="https://img.hawa130.com/image-20220621173213485.png" alt="image-20220621173213485"></p></li><li><p>视图消解法</p><p><img src="https://img.hawa130.com/image-20220621173236936.png" alt="image-20220621173236936"></p></li></ul></li></ul></li><li><p>更新视图</p><ul><li>插入 INSERT</li><li>删除 DELETE</li><li>修改 UPDATE</li></ul></li></ol><p><img src="https://img.hawa130.com/image-20220621173432673.png" alt="image-20220621173432673"></p><ol><li>视图的作用<ul><li>简化用户的操作</li><li>使用户能以多种角度看待同一数据</li><li>对重构数据库提供了一定程度的逻辑独立性</li><li>对机密数据提供安全保护</li></ul></li></ol><h2 id="第四章-数据库安全性"><a href="#第四章-数据库安全性" class="headerlink" title="第四章 数据库安全性"></a>第四章 数据库安全性</h2><h3 id="定义"><a href="#定义" class="headerlink" title="定义"></a>定义</h3><p>是指保护数据库以防止不合法使用所造成的数据泄露，更改和破坏</p><h3 id="不安全因素"><a href="#不安全因素" class="headerlink" title="不安全因素"></a>不安全因素</h3><ol><li>非授权用户对数据库的恶意存取和破坏</li><li>数据库中重要或敏感数据被泄露</li><li>安全环境的脆弱性</li></ol><h3 id="数据库的安全性控制"><a href="#数据库的安全性控制" class="headerlink" title="数据库的安全性控制"></a>数据库的安全性控制</h3><ol><li><p>用户身份鉴别</p><ul><li>每个用户由用户名 username 和用户标识号 UID 组成</li><li>常用的用户身份鉴别方法<ul><li>静态口令鉴别：用户名和密码</li><li>动态口令鉴别：短信验证码</li><li>生物特征识别：指纹，声纹，虹膜</li><li>智能卡鉴别</li></ul></li></ul></li><li><p>存取控制</p><ul><li><p>存取控制机制主要包括定义用户权限和合法权限检查两部分</p></li><li><p>自主存取控制 DAC</p><ul><li><p>用户权限由两个要素组成：数据库对象和操作类型</p></li><li><p>授权：授予和收回</p><ul><li><p>授权</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">grant</span> <span class="operator">&lt;</span>权限<span class="operator">&gt;</span> <span class="keyword">on</span> <span class="operator">&lt;</span>对象类型<span class="operator">&gt;</span> <span class="operator">&lt;</span>对象名<span class="operator">&gt;</span></span><br><span class="line"><span class="keyword">to</span> <span class="operator">&lt;</span>用户<span class="operator">&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>收回</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">revoke</span> <span class="operator">&lt;</span>权限 <span class="operator">&gt;</span><span class="keyword">on</span> <span class="operator">&lt;</span>对象类型<span class="operator">&gt;</span> <span class="operator">&lt;</span>对象名<span class="operator">&gt;</span></span><br><span class="line"><span class="keyword">from</span> <span class="operator">&lt;</span>用户<span class="operator">&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>with grant option 子句使得获得某种权限的用户把权限再授予其他用户</p></li></ul></li><li><p>数据库角色</p><ul><li><p>定义：是被命名的一组与数据库操作相关的权限，是权限的集合</p></li><li><p>使用</p><ul><li><p>角色的创建：</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">create</span> role <span class="operator">&lt;</span>角色名<span class="operator">&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>给角色授权：</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">grant</span> <span class="operator">&lt;</span>权限<span class="operator">&gt;</span> <span class="keyword">on</span> <span class="operator">&lt;</span>对象类型<span class="operator">&gt;</span><span class="operator">&lt;</span>对象名<span class="operator">&gt;</span><span class="keyword">to</span><span class="operator">&lt;</span>角色名<span class="operator">&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>将一个角色授予其他的角色或用户</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">grant</span> <span class="operator">&lt;</span>角色<span class="number">1</span><span class="operator">&gt;</span>,...<span class="keyword">to</span> <span class="operator">&lt;</span>角色<span class="number">3</span><span class="operator">&gt;</span>[,<span class="operator">&lt;</span>用户<span class="number">1</span><span class="operator">&gt;</span>]</span><br><span class="line">[<span class="keyword">with</span> admin option]</span><br></pre></td></tr></table></figure></li><li><p>角色权限的收回</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">revoke</span> <span class="operator">&lt;</span>权限<span class="operator">&gt;</span> <span class="keyword">on</span> <span class="operator">&lt;</span>对象类型<span class="operator">&gt;</span> <span class="operator">&lt;</span>对象名<span class="operator">&gt;</span> </span><br><span class="line"><span class="keyword">from</span> <span class="operator">&lt;</span>角色<span class="operator">&gt;</span></span><br></pre></td></tr></table></figure></li></ul></li></ul></li><li><p>自主存取控制，仅仅通过对数据的存取权限来进行安全控制，而数据本身并无安全性标记</p></li></ul></li><li><p>强制存取控制 MAC</p><ul><li>全部实体分为主体和客体<ul><li>主体是系统中活动实体，实际用户和各进程</li><li>客体是系统中被动实体，包括文件、基本表、索引、视图等</li><li>对于主体和客体，DBMS 为每个实例（值）指派一个敏感度标记</li><li>敏感度标记被分为若干级别：绝密、机密、可信、公开</li><li>主体的敏感度标记称为许可证级别，客体的敏感度级别称为密级</li></ul></li><li>主体对任何客体的存取需遵循的规则<ul><li>仅当主体的许可证级别大于或等于客体的密级，该主体才能读取相应的客体</li><li>仅当主体的许可证级别小于或等于客体的密级，该主体才能写相应的客体</li></ul></li></ul></li></ul></li><li><p>视图控制：为不同用户定义不同的视图，把数据库对象限制在一定范围内</p></li><li><p>数据加密存储和加密传输</p></li></ol><h2 id="第五章-数据库完整性"><a href="#第五章-数据库完整性" class="headerlink" title="第五章 数据库完整性"></a>第五章 数据库完整性</h2><h3 id="定义-1"><a href="#定义-1" class="headerlink" title="定义"></a>定义</h3><p>是指数据的正确性和相容性</p><h3 id="实体完整性"><a href="#实体完整性" class="headerlink" title="实体完整性"></a>实体完整性</h3><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> student(</span><br><span class="line">sno <span class="type">char</span>(<span class="number">9</span>) <span class="keyword">primary</span> key,<span class="comment">/*列级定义主码*/</span></span><br><span class="line">sname ...</span><br><span class="line">cno ...</span><br><span class="line">...</span><br><span class="line">);</span><br><span class="line">或者</span><br><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> student(</span><br><span class="line">sno <span class="type">char</span>(<span class="number">9</span>)，</span><br><span class="line">sname ...</span><br><span class="line">cno ...</span><br><span class="line">...</span><br><span class="line"><span class="keyword">primary</span> key (sno)<span class="comment">/*表级定义主码*/</span></span><br><span class="line">);</span><br></pre></td></tr></table></figure><p>将属性组定义为主码只能在表级</p><h3 id="参照完整性"><a href="#参照完整性" class="headerlink" title="参照完整性"></a>参照完整性</h3><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> student(</span><br><span class="line">sno <span class="type">char</span>(<span class="number">9</span>)，</span><br><span class="line">sname ...</span><br><span class="line">cno ...</span><br><span class="line">...</span><br><span class="line"><span class="keyword">primary</span> key (sno,cno),<span class="comment">/*表级定义实体完整性*/</span></span><br><span class="line"><span class="keyword">foreign</span> key (sno) <span class="keyword">references</span> student(sno),<span class="comment">/*表级定义参照完整性*/</span></span><br><span class="line"><span class="keyword">foreign</span> key (cno) <span class="keyword">references</span> course(cno)<span class="comment">/*表级定义参照完整性*/</span></span><br><span class="line">);</span><br></pre></td></tr></table></figure><h3 id="用户定义的完整性"><a href="#用户定义的完整性" class="headerlink" title="用户定义的完整性"></a>用户定义的完整性</h3><ol><li><p>属性上的约束条件</p><ol><li><p>列值非空</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> student</span><br><span class="line">(sno <span class="type">char</span>(<span class="number">9</span>) <span class="keyword">not</span> <span class="keyword">null</span>,<span class="comment">/*属性不允许取空*/</span></span><br><span class="line">sname ... <span class="keyword">not</span> <span class="keyword">null</span>,</span><br><span class="line">cno... <span class="keyword">not</span> <span class="keyword">null</span>,</span><br><span class="line"><span class="keyword">primary</span> key (sno, cno)</span><br><span class="line">);</span><br></pre></td></tr></table></figure></li><li><p>列值唯一</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> student</span><br><span class="line">(sno <span class="type">char</span>(<span class="number">9</span>) <span class="keyword">not</span> <span class="keyword">null</span>,</span><br><span class="line">sname ... <span class="keyword">unique</span> <span class="keyword">not</span> <span class="keyword">null</span>,<span class="comment">/*列值唯一且不取空*/</span></span><br><span class="line">cno... <span class="keyword">not</span> <span class="keyword">null</span>,</span><br><span class="line"><span class="keyword">primary</span> key (sno, cno)</span><br><span class="line">);</span><br></pre></td></tr></table></figure></li><li><p>检查列值是否满足一个条件表达式（check 表达式）</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> student</span><br><span class="line">(sno <span class="type">char</span>(<span class="number">9</span>) <span class="keyword">not</span> <span class="keyword">null</span>,</span><br><span class="line">sname ... <span class="keyword">not</span> <span class="keyword">null</span>,</span><br><span class="line">ssex <span class="type">char</span>(<span class="number">2</span>) <span class="keyword">check</span> (ssex <span class="keyword">in</span>(<span class="string">&#x27;男&#x27;</span>,<span class="string">&#x27;女&#x27;</span>)),<span class="comment">/*性别只允许取男女*/</span></span><br><span class="line">...</span><br><span class="line"><span class="keyword">primary</span> key (sno, cno)</span><br><span class="line">);</span><br></pre></td></tr></table></figure></li></ol></li><li><p>元组上的约束条件</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">create</span> <span class="keyword">table</span> student</span><br><span class="line">(sno <span class="type">char</span>(<span class="number">9</span>) <span class="keyword">not</span> <span class="keyword">null</span>,</span><br><span class="line">sname ... <span class="keyword">not</span> <span class="keyword">null</span>,</span><br><span class="line">ssex <span class="type">char</span>(<span class="number">2</span>),</span><br><span class="line">...</span><br><span class="line"><span class="keyword">primary</span> key (sno, cno)</span><br><span class="line"><span class="keyword">check</span> (ssex<span class="operator">=</span><span class="string">&#x27;女&#x27;</span> <span class="keyword">or</span> sname <span class="keyword">not</span> <span class="keyword">like</span> <span class="string">&#x27;Ms.%&#x27;</span>),<span class="comment">/*性别女的不允许叫 Ms.%*/</span></span><br><span class="line">);</span><br></pre></td></tr></table></figure></li></ol><h3 id="完整性约束命名子句"><a href="#完整性约束命名子句" class="headerlink" title="完整性约束命名子句"></a>完整性约束命名子句</h3><ol><li><p>在创建表时，可以增加、删除一个完整性约束条件</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">constraint</span> <span class="operator">&lt;</span>完整性约束条件名<span class="operator">&gt;</span> <span class="operator">&lt;</span>完整性约束条件<span class="operator">&gt;</span></span><br></pre></td></tr></table></figure></li><li><p>修改表中的完整性约束限制</p><figure class="highlight sql"><table><tr><td class="code"><pre><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span>表名 </span><br><span class="line"><span class="keyword">Drop</span> <span class="keyword">Constraint</span><span class="operator">&lt;</span>完整性约束条件<span class="operator">&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">ALTER</span> <span class="keyword">TABLE</span>表名 </span><br><span class="line"><span class="keyword">ADD</span> <span class="keyword">Constraint</span><span class="operator">&lt;</span>完整性约束条件<span class="operator">&gt;</span><span class="operator">&lt;</span><span class="keyword">CHECK</span>短语<span class="operator">&gt;</span></span><br></pre></td></tr></table></figure></li></ol><h2 id="第六章-关系数据理论"><a href="#第六章-关系数据理论" class="headerlink" title="第六章 关系数据理论"></a>第六章 关系数据理论</h2><ol><li><p>关系模式的问题</p><ul><li>数据冗余</li><li>更新异常</li><li>插入异常</li><li>删除异常</li></ul></li><li><p>函数依赖</p><p>x 函数确定 y，y 函数依赖于 x，写为 $x\to y$</p><ul><li>$x\to y$，$y\subsetneq x$，非平凡函数依赖</li><li>$x\to y$，$y\subseteq x$，平凡函数依赖</li><li>$x\to y$，$y\to x$，记作$x\leftarrow \to y$</li><li>y 不函数依赖于x，记作 $x\nrightarrow y$</li><li>完全函数依赖：$x\to y$，且对 x 的子集 x’，都有$x’\nrightarrow y$，则 y 对 x 完全函数依赖，记作 $x \stackrel{F}\to y$</li><li>不完全函数依赖：$x\to y$，但y 对 x 不完全函数依赖，记作 $x \stackrel{P}\to y$</li><li>传递依赖</li></ul></li><li><p>范式</p><p><img src="https://img.hawa130.com/image-20220621230044910.png" alt="image-20220621230044910"></p><ul><li>1NF：表不可再分</li><li>2NF：任意候选码都是非主属性的完全函数依赖</li><li>3NF ：不存在 ”关键字-&gt;==非关键字-&gt;非关键字==“</li><li>BCNF：即每个依赖左边必包含码，即不存在”==关键字x-&gt;关键字y==-&gt;非关键字“</li></ul></li></ol><h2 id="第七章-数据库设计"><a href="#第七章-数据库设计" class="headerlink" title="第七章 数据库设计"></a>第七章 数据库设计</h2><ol><li><h5 id="数据库设计步骤，了解设计的各个阶段"><a href="#数据库设计步骤，了解设计的各个阶段" class="headerlink" title="数据库设计步骤，了解设计的各个阶段"></a>数据库设计步骤，了解设计的各个阶段</h5><p><img src="https://img.hawa130.com/image-20220621230226151.png" alt="image-20220621230226151"></p><ul><li><p>需求分析</p></li><li><p>概念结构设计</p></li><li><p>逻辑结构设计</p></li><li><p>物理结构设计</p></li><li><p>数据库实施</p></li><li><p>数据库运行和维护</p><p><img src="https://img.hawa130.com/image-20220621230421175.png" alt="image-20220621230421175"></p></li></ul></li><li><h5 id="课本图-7-7-7-9-的实例"><a href="#课本图-7-7-7-9-的实例" class="headerlink" title="课本图 7.7-7.9 的实例"></a>课本图 7.7-7.9 的实例</h5><p><img src="https://img.hawa130.com/image-20220621230737549.png" alt="image-20220621230737549"></p><p><img src="https://img.hawa130.com/image-20220621230758999.png" alt="image-20220621230758999"></p><p>图 7.11</p><p><img src="https://img.hawa130.com/image-20220621230839354.png" alt="image-20220621230839354"></p><p>课后题 7,8,10,11</p></li></ol>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;题型&quot;&gt;&lt;a href=&quot;#题型&quot; class=&quot;headerlink&quot; title=&quot;题型&quot;&gt;&lt;/a&gt;题型&lt;/h2&gt;&lt;p&gt;单选：10 个 × 2 分&lt;/p&gt;
&lt;p&gt;填空：10 个 × 1 分&lt;/p&gt;
&lt;p&gt;综合应用题：3 个，每个 10-30 分（考察 2-6 
      
    
    </summary>
    
      <category term="学习" scheme="http://smilin9.com/categories/%E5%AD%A6%E4%B9%A0/"/>
    
    
      <category term="复习" scheme="http://smilin9.com/tags/%E5%A4%8D%E4%B9%A0/"/>
    
  </entry>
  
  <entry>
    <title>朝花夕誓</title>
    <link href="http://smilin9.com/2022/06/17/%E6%9C%9D%E8%8A%B1%E5%A4%95%E8%AA%93/"/>
    <id>http://smilin9.com/2022/06/17/朝花夕誓/</id>
    <published>2022-06-17T08:53:00.000Z</published>
    <updated>2022-12-12T14:57:53.177Z</updated>
    
    <content type="html"><![CDATA[<p>朝花夕誓——于离别之朝，束起约定之花</p><p>救命，好久没有看电影这么想哭了，但是真的很感动，以后一定二刷。</p><p>印象最深的是玛奇亚剪去长发之后再见艾瑞尔，艾瑞尔打仗受了伤，在玛奇亚准备离开的时候，艾瑞尔那一句 ”不要走，妈妈“，突然就泪崩。</p><p>我以为会讲爱情的，也一直抱着这样的心态看的，但是看到这才突然发现，原来虽然他们的年龄相差不大，但是艾瑞尔把玛奇亚一直是当母亲看的，而玛奇亚自己没有母亲，她不知道母亲是什么，应该怎么做，她也是第一次当母亲。尽管她也只是十六七岁的年纪，但为了艾瑞尔，她试着去做一个母亲，去成熟，去照顾好自己和她所谓的孩子。就像剧情里说的，是她教会了艾瑞尔什么是爱，怎样去爱一个人，我想她是一个合格的母亲，她做得很好。</p><p>同为离别之族，克里德至死都想不明白为什么玛奇亚和蕾莉亚都变了，同样经历了家园被毁灭，为什么她们可以不像自己一样活在复仇之中，反而看起来都过得比他幸福。但是她们真的变了吗，蕾莉亚只是想再看看自己的孩子，玛奇亚只是有了艾瑞尔这个牵挂，这是她们的希比奥尔啊。相比于在远离尘嚣的土地上过着每天织布的枯燥生活，我想对她们来说找到自己的希比奥尔才更能让她们感到幸福吧。她们的牵挂正是支撑她们活下去的动力。</p><p>最后的那句 ”让我们去邂逅新的离别吧”，莫名有一种悲伤的感觉。世人都想追求长生，但长生真的好吗，看着身边的人一个个老去，离开这个世界，固然长寿，但或许也并不是一件值得开心的事情吧。但这就是长生的代价，是离别之族的命运。</p><p>最后艾瑞尔有了自己的爱人、孩子、后代，而玛奇亚也见到了他的最后一面，看着自己亲手抚养长大成人的孩子离开这个世界，虽然还是因为他们的分开感到难过，但对玛奇亚来说，可能也算是给这一场离别画上了句点。</p><blockquote><p>“欢迎回家”</p><p>“我回来了”</p><p>“早上好”</p><p>“你被骗啦，你以为是我蜕的壳对不对”</p><p>“那我出生的地方呢‘’</p><p>“痒痒虫来了哦“</p><p>“妈妈笑了“</p><p>“妈妈你和大家不一样”</p><p>“为什么，你来这里后，就变得不像妈妈了”</p><p>“不准弄哭我妈妈”</p><p>“我只要有妈妈在就好”</p><p>“我要保护妈妈”</p><p>“我想保护她，可是现在的我没法保护她，我保护不了她”</p><p>“为什么她对我这么在乎”</p><p>“是你教会了我”</p><p>“不要走啊 妈妈”</p><p>“我不哭了，我是妈妈嘛”</p><p>“妈妈，我最喜欢你了”</p><p>”一路走好，艾瑞尔。吃晚饭前要回家。“</p><p>“欢迎回家”</p></blockquote><p>如果你没有如期归来，这就是离别的意义。</p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;p&gt;朝花夕誓——于离别之朝，束起约定之花&lt;/p&gt;
&lt;p&gt;救命，好久没有看电影这么想哭了，但是真的很感动，以后一定二刷。&lt;/p&gt;
&lt;p&gt;印象最深的是玛奇亚剪去长发之后再见艾瑞尔，艾瑞尔打仗受了伤，在玛奇亚准备离开的时候，艾瑞尔那一句 ”不要走，妈妈“，突然就泪崩。&lt;/p&gt;
&lt;p&gt;
      
    
    </summary>
    
      <category term="生活" scheme="http://smilin9.com/categories/%E7%94%9F%E6%B4%BB/"/>
    
    
      <category term="电影" scheme="http://smilin9.com/tags/%E7%94%B5%E5%BD%B1/"/>
    
  </entry>
  
  <entry>
    <title>网安数基复习</title>
    <link href="http://smilin9.com/2022/06/16/%E7%BD%91%E5%AE%89%E6%95%B0%E5%9F%BA%E5%A4%8D%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
    <id>http://smilin9.com/2022/06/16/网安数基复习笔记/</id>
    <published>2022-06-16T15:42:00.000Z</published>
    <updated>2022-12-12T14:57:53.177Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Part2"><a href="#Part2" class="headerlink" title="Part2"></a><strong>Part2</strong></h2><p><strong>1. Bloom过滤器的设计，查询错误率估计</strong></p><div class="table-container"><table><thead><tr><th style="text-align:center">符号</th><th style="text-align:center">含义</th></tr></thead><tbody><tr><td style="text-align:center">k</td><td style="text-align:center">散列函数的数目</td></tr><tr><td style="text-align:center">m</td><td style="text-align:center">位向量的长度</td></tr><tr><td style="text-align:center">n</td><td style="text-align:center">集合中元素的个数</td></tr></tbody></table></div><p>对于集合 $S={x_1,x_2,…,x_n}$ 中的⼀个元素而言，通过散列函数映射到位向量上，其某⼀位置被置 1 的概率是 $\frac{1}{m}$，为 0 的概率是 $1-\frac{1}{m}$，在将集合内所有元素通过 $k$ 个散列函数映射到向量上之后，某⼀位仍然是 0 的概率是</p><script type="math/tex; mode=display">P_{0}=(1-\frac{1}{m})^{kn}=[(1-\frac{1}{m})^{-m}]^{-\frac{kn}{m}}\approx e^{-\frac{kn}{m}}</script><p>每次散列函数都刚好选中1的区域的概率，即 Bloom 的帧数误判率（false positive rate）$P$ 为</p><script type="math/tex; mode=display">P=(1-P_{0})^{k}=(1-e^{-\frac{kn}{m}})^{k}</script><ul><li>特性：<ul><li>⼀个元素如果判断结果为存在的时候元素不⼀定存在，但是判断结果为不存在的时候则⼀定不存在。</li><li>布隆过滤器可以添加元素，但是不能删除元素。因为删掉元素会导致误判率增加。</li></ul></li><li>优点：<ul><li>相比于其它的数据结构，布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插⼊/查询时间都是常数 O(K)，另外，散列函数相互之间没有关系，方便由硬件并行实现。布隆过滤器不需要存储元素本身，在某些对保密要求非常严格的场合有优势。</li></ul></li></ul><p><strong>2. 集合近似相等的判断 Simhash 相似哈希算法，分布之间的距离度量</strong></p><p><strong>集合相等的判断：</strong></p><ul><li><p>对集合中的元素一一比较，时间复杂度 $O(n^2)$</p></li><li><p>将两个集合的元素分别排序，然后顺序比较，时间复杂度 $O(n\log  n)$</p></li><li><p>计算两个集合的信息指纹，直接比较，</p><script type="math/tex; mode=display">S={e_{1},e_{2},..,e_{n}}</script><script type="math/tex; mode=display">FP(S)=FP(e_{1})+FP(e_{2})+...+FP(e_{n})</script></li></ul><p>​        如果两个集合相同，则其指纹⼀定相同；如果不同，则指纹相同的概率很小。</p><p><strong>集合近似相等的判断</strong> <strong>Simhash</strong> <strong>相似哈希算法：</strong></p><p>信息指纹：通过提取⼀个信息的特征，通常是⼀组词或者⼀组词+权重，然后根据这组词调⽤特别的算法（例如 MD5 算法），将之转化为⼀组代码，这组代码就是标识这段信息的指纹。</p><p>假设⼀个网页有若⼲词：$t_1,t_2,…,t_8$，每个词的权重分布为：$w_1,w_2,…,w_8$，每个词哈希值指纹为 8bit，如</p><p>$Hash(t_1)=10100110$。</p><ul><li><p>Step1. 扩展：将 8 位的⼆进制的指纹扩展成 8 个实数 $r_1,r_2,…,r_8$，根据 1 加 0 减的规则，做相应的权重操作。然后遍历第⼆个词，操作的过程相同。例如， $Hash(t_1)=10100110$。</p><p><img src="https://img.hawa130.com/image-20220617223224476.png" alt="image-20220617223224476" style="zoom:80%;" /><img src="https://img.hawa130.com/image-20220617223333223.png" alt="image-20220617223333223" style="zoom:80%;" /><img src="https://img.hawa130.com/image-20220617223618456.png" alt="image-20220617223618456" style="zoom:67%;" /></p></li><li><p>Step 2. 收缩：将最后的由权重值计算得到的网页总哈希值。如果某个位的值大于 0，则此位置上的值置 1，否则置 0。</p><p><img src="https://img.hawa130.com/image-20220617225011895.png" alt="image-20220617225011895"></p></li></ul><p>如果 2 个网页相同，则相似哈希值必定相同。两个网页的相似哈希相差越小，两个网页的相似性越⾼。</p><p><strong>分布之间的距离度量：</strong></p><p>Q：两个分布 p 和 q 之间的距离有多大？</p><ul><li><p>KL 散度：KL 散度可以⽤于描述两个分布之间的距离，假设 $p(x)$ 与 $q(x)$ 是随机变量 $X$ 的分布，则其 KL 散度为</p><script type="math/tex; mode=display">D(p||q)=\int_{-∞}^{+∞}p(x)log\frac{p(x)}{q(x)}dx</script></li><li><p>离散情况下</p><script type="math/tex; mode=display">D(p||q)=\sum_{i=1}^{n}p(x)log\frac{p(x)}{q(x)}dx</script></li></ul><p><img src="https://img.hawa130.com/image-20220617230144856.png" alt="image-20220617230144856"></p><p><strong>3. 贝叶斯公式，随机变量参数的最大似然估计</strong></p><p><strong>贝叶斯公式：</strong> 一种可以利⽤先验概率计算后验概率的方法。</p><script type="math/tex; mode=display">P(B|A)=\frac{P(A|B)P(B)}{P(A)}</script><p><strong>最大似然估计：</strong> 通过数据估计未知参数 $θ$</p><ul><li><p>基本思想： 给定样本取值后，该样本最有可能来⾃参数 $θ$ 为何值的总体。⼀般步骤：</p><ul><li><p>写出似然函数</p><script type="math/tex; mode=display">L(θ_{1},θ_{2},...,θ_{n})=\begin{cases}\prod_{i=1}^{n}p(x_i;θ_{1},θ_{2},...,θ_{n})\\\prod_{i=1}^{n}f(x_i;θ_{1},θ_{2},...,θ_{n}) \end{cases}</script></li><li><p>对似然函数取对数，得 $\ln L(θ)$</p></li><li><p>两边同时求导数，得 $\frac{d\ln L(θ)}{dθ}$</p></li><li><p>令导数等于 0 解出似然⽅程，（$\frac{d\ln L(θ)}{dθ}=0$）</p></li></ul></li></ul><p><strong>4. 朴素贝叶斯分类方法</strong></p><p>贝叶斯分类器是⼀个统计分类器。能够预测类别所属的概率。</p><p>设 X 是类标号未知的数据样本。设 H 为某种假定，如数据样本 X 属于某特定的类 C。对于分类问题，我们希望确定  $P(H|X)$，即给定观测数据样本 X，假定 H 成⽴的概率。贝叶斯定理给出了计算  $P(H|X)$ 的⽅法:</p><script type="math/tex; mode=display">P(H|X)=\frac{P(X|H)P(H)}{P(X)}</script><ul><li>$P(H)$ 是先验概率，或称 H 的先验概率。 $P(X|H)$ 代表假设 H 成⽴的情况下，观察到 X 的概率。</li><li>$P(H|X)$ 是后验概率，或称条件 X 下 H 的后验概率。</li></ul><p><strong>5. 信息熵，信息增益，简单的决策树的构建方法</strong></p><p><strong>信息熵：</strong> 解决了对信息的量化度量问题。</p><p><strong>信息增益（Information Gain）：</strong></p><p>We want to determine which attribute in a given set of training feature vectors is most useful for discriminating between the classes to be learned. Information gain tells us how important a given attribute of the feature vectors is. We will use it to decide the ordering of attributes in the nodes of a decision tree.</p><p>Entropy $H(X)$ of a random variable $X$</p><script type="math/tex; mode=display">H(X)=-\sum_{i=1}^{n}p(x_i)\log_{2}{p(x_i)}</script><p>Specific conditional entropy（条件熵）$H(X|Y=v)$ of $X$ given $Y=v$</p><script type="math/tex; mode=display">H(X|Y=v)=H(X)=-\sum_{i=1}^{n}p(x_i|Y=v)\log_{2}{p(x_i|Y=v)}</script><p>Conditional entropy $H(X|Y=v)$ of $X$ given $Y$</p><script type="math/tex; mode=display">H(X|Y)=\sum_{v∈values(Y)}P(Y=v)H(X|Y=v)</script><p>Mutual information (aka Information Gain) of $X$ and $Y$</p><script type="math/tex; mode=display">I(X,Y)=H(X)-H(X|Y)=H(Y)-H(Y|X)</script><p><strong>简单的决策树的构建⽅法：</strong></p><p>node=root of decision tree</p><p>Main loop:</p><ol><li><p>A &lt;- the “best” decision attribute for the next node.</p></li><li><p>Assign A as decision attribute for node.</p></li><li><p>For each value of A, create a new descendant of node.</p></li><li><p>Sort training examples to leaf nodes.</p></li><li><p>If training examples are perfectly classified, stop. Else, recurse over new leaf nodes.</p></li></ol><p><strong>6. 差分隐私的定义，后加工不变性、串行合成性、并行合成性的证明</strong></p><p><strong>差分隐私（Differential privacy）的定义：</strong></p><p><img src="https://img.hawa130.com/image-20220618014114981.png" alt="image-20220618014114981"></p><p><strong>后加工不变性（Posting-processing）：</strong></p><p><img src="https://img.hawa130.com/image-20220618014153452.png" alt="image-20220618014153452"></p><p><strong>串行合成性（Sequential composition）：</strong></p><p><img src="https://img.hawa130.com/image-20220618014218610.png" alt="image-20220618014218610"></p><p><strong>并行合成性（Parallel Composition）：</strong></p><p><img src="https://img.hawa130.com/image-20220618014241360.png" alt="image-20220618014241360"></p><p><strong>7. 差分隐私的 Laplace机制；本地差分隐私中的随机响应技术；差分隐私的Laplace机制：</strong></p><p>全局敏感度：</p><p><img src="https://img.hawa130.com/image-20220618014348205.png" alt="image-20220618014348205"></p><script type="math/tex; mode=display">A(x)=f(x)+Lap(\frac{GS_f}{∊})\ is\ ∊-DP</script><p>Laplace 分布：</p><script type="math/tex; mode=display">f(x|\mu,b)=\frac{1}{2b}e^{-\frac{|x-\mu|}{b}}</script><p>为了达到 ∊-DP，可以给输出结果加上⼀个噪⾳进⾏掩盖和混淆：</p><script type="math/tex; mode=display">f'(D)=f(D)+X</script><p>其中 <script type="math/tex">X</script> 是需要添加的噪声，添加噪声后的结果应满⾜：</p><script type="math/tex; mode=display">\frac{P[f'(D)=t]}{P[f'(D')=t]}=\frac{P[f(D)+X=t]}{P[f(D')+X=t]}=\frac{P[X=t-f(D)]}{P[X=t-f(D')]}\leqslant e^{∊}</script><p>令 $d=f(D)-f(D’)$，$x=t-f(D)$，</p><script type="math/tex; mode=display">\frac{P(X=x)}{P(X=x+d)}\leqslant e^{∊}</script><p>如果 $X \sim Lap(b)$，</p><script type="math/tex; mode=display">\frac{P(Lap(b)=x)}{P(Lap(b)=x+d)}=\frac{\frac{1}{2b}e^{\frac{|x|}{b}}}{\frac{1}{2b}e^{\frac{|x+d|}{b}}}=e^{\frac{|x+d|-|x|}{b}} \leqslant e^{\frac{d}{b}} \leqslant e^{\frac{\Delta f}{b}}</script><p>要想让上式小于 $e^∊$ ，只需要让 $\frac{\Delta f}{b}=∊$，即 $\frac{\Delta f}{∊}=b$，因此加入噪声 $Lap(b)=Lap(\frac{\Delta f}{∊})$。</p><p><strong>本地差分隐私中的随机响应技术：</strong></p><p>本地差分隐私：认为第三方是不可信的，所以本地差分隐私保护的是用户上传数据到第三方的过程，差分隐私机制运行在各个用户的本地。</p><p>随机响应技术（randomized response）：</p><blockquote><p>假设有n个⽤户，其中艾滋病患者的⽐例为π，我们希望对π进⾏统计。于是对⽬标⽤户发起问卷调查：“你是否为艾滋病患者？”显然，如果直接获得⽤户的相应数据进⾏统计，⼀旦数据泄露，那么⽤户隐私随即泄露。因此，我们假设存在⼀枚⾮均匀的硬币，其正⾯向上的概率为p，反⾯向上的概率为1-p。抛出该硬币，若正⾯向上，则回答真实答案，反⾯向上，则回答相反的答案。</p></blockquote><p>显然，$\Pr[X_i=是]=\pi p+(1-\pi)(1-p)$，$\Pr[X_i=否]=(1-\pi)p+\pi(1-p)$。设回答 “是” 的人数为 n1，回答 “否” 的人数为 n2。⽤极大似然估计（Max Likehood Estimation）对 $\pi$ 统计结果进行估计。首先构建似然函数：</p><script type="math/tex; mode=display">L(\pi)=[\pi p+(1-\pi)(1-p)]^{n_1}[(1-\pi)p+\pi(1-p)]^{n-n_1}</script><p>可以求出 $\pi$ 的极大似然估计，并验证是 $\pi$ 的无偏估计，由此可以得到患病的总人数。</p><p><strong>8. 简单的传染病传播模型 SI；免疫方法；网络中节点的度中心性度量</strong></p><p><strong>简单的传染病传播模型 SI：</strong></p><p>SI : lSusceptible, and once you catch the disease, you remain infectious for the rest of your life.</p><p>假设条件：</p><ul><li><p>人群分为易感染者（Susceptible）和已感染者（Infective）两类，简称健康者和病人。t 时刻这两类人在总人数中所占的比例分别记为 $s(t)$ 和 $i(t)$，初始时刻（$t = 0$）病人的比例为 $i_0$。</p></li><li><p>在疾病传播期内所考察地区的总人数 N 不变，既不考虑生死，也不考虑迁移，时间以天为计量单位。</p></li><li><p>每个病人每天有效接触的平均人数是常数 l，l 称为日接触率。当病人与健康者有效接触时，使健康者受感染变为病人。</p><script type="math/tex; mode=display">i(t)=\frac{1}{1+(\frac{1}{i_0})e^{-\lambda t}}</script></li></ul><p>当 $t\to \infty$ 时，$i \to 1$，即所有人终将被传染变为病人，显然不符合实际情况。其原因是模型中没有考虑到病人可以治愈，人群中的健康者只能变成病人，病人不会再变成健康者。</p><p>这个模型在传染病流⾏的前期是可用的，可用它来预报传染病高潮的到来：</p><script type="math/tex; mode=display">t_m=\lambda^{-1}\ln(\frac{1}{i_0}-1)</script><p><strong>免疫方法/免疫策略：</strong></p><blockquote><p>Pastor-Satorras 等的研究表明：在资源有限的情况下，优先保护节点度数比较大的节点比随机选择节点进行保护效果要好得多</p></blockquote><ul><li><p>随机免疫：随机免疫是在网络中随机抽取一部分节点进行免疫。研究表明，采取这种策略的话，需要对网络中几乎所有的节点都进行免疫才能保证最终消灭传染病。</p></li><li><p>选择免疫：选择免疫是在网络中抽取度最大的节点进行免疫。针对 BA 模型，采取选择免疫策略，即使有效传播率变化，也可以只免疫很小一部分节点就保证消灭传染病。</p></li><li><p>熟人免疫：熟人免疫采取的是随机抽取⼀部分节点，然后对每个节点随机选⼀个与之相连的“邻居”节点来进行免疫。</p><p>由于在无尺度网络中，度大的节点可以与非常多的节点相连，因此选择“邻居”免疫的话，碰到度大节点的概率会比碰到度小节点的概率大得多。所以熟人免疫要比随机免疫有效得多，只略差于选择免疫。</p></li></ul><p><strong>网络中节点的度中心性度量：</strong></p><p>直观上看，⼀个节点的度越大就意味着这个节点在某种意义上越 “重要”（“能力大”）。</p><p>度(degree)：节点 i 的度 ki 定义为与该节点连接的其他节点的数⽬。</p><p>网络的平均度：网络中所有节点的度和的平均值。</p><p>度分布函数 $p(k)$：随机选定节点的度为 k 的概率。</p><p><strong>9. 齐次 poisson 点过程的定义；在 HPPP 中，相邻节点之间的距离分布；Campbel 定理的应用，掌握计算齐次 poisson 点过程中，空间点的某函数的和的期望的计算方法。</strong></p>]]></content>
    
    <summary type="html">
    
      
      
        &lt;h2 id=&quot;Part2&quot;&gt;&lt;a href=&quot;#Part2&quot; class=&quot;headerlink&quot; title=&quot;Part2&quot;&gt;&lt;/a&gt;&lt;strong&gt;Part2&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;1. Bloom过滤器的设计，查询错误率估计&lt;/strong&gt;&lt;/
      
    
    </summary>
    
      <category term="学习" scheme="http://smilin9.com/categories/%E5%AD%A6%E4%B9%A0/"/>
    
    
      <category term="复习" scheme="http://smilin9.com/tags/%E5%A4%8D%E4%B9%A0/"/>
    
  </entry>
  
  <entry>
    <title>RSA_STARTER</title>
    <link href="http://smilin9.com/2022/05/08/RSA_STARTER/"/>
    <id>http://smilin9.com/2022/05/08/RSA_STARTER/</id>
    <published>2022-05-08T17:42:00.000Z</published>
    <updated>2022-12-12T14:57:53.173Z</updated>
    
    <content type="html"><![CDATA[<p>这个超快！</p><p>我看谁不是速通（bushi</p><span id="more"></span><p>最后一块内容，没想到意外地顺利，舒服捏。</p><h2 id="RSA-Starter-1"><a href="#RSA-Starter-1" class="headerlink" title="RSA Starter 1"></a>RSA Starter 1</h2><h3 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h3><p>All operations in RSA involve <a href="https://en.wikipedia.org/wiki/Modular_exponentiation">modular exponentiation</a>.</p><p>Modular exponentiation is an operation that is used extensively in cryptography and is normally written like: <code>2¹⁰ mod 17</code></p><p>You can think of this as raising some number to a certain power (<code>2¹⁰ = 1024</code>), and then taking the remainder of the division by some other number (<code>1024 mod 17 = 4</code>). In Python there’s a built-in operator for performing this operation: <code>pow(base, exponent, modulus)</code></p><p>In RSA, modular exponentiation, together with the problem of prime factorisation, helps us to build a “<a href="https://en.wikipedia.org/wiki/Trapdoor_function">trapdoor function</a>“. This is a function that is easy to compute in one direction, but hard to do in reverse unless you have the right information. It allows us to encrypt a message, and only the person with the key can perform the inverse operation to decrypt it.</p><p>Find the solution to <code>101¹⁷ mod 22663</code></p><h3 id="Analyze"><a href="#Analyze" class="headerlink" title="Analyze"></a>Analyze</h3><p>模幂运算？有种回到做数论题的错觉（出戏。</p><p>不过 pow() 是之前就用过的东西诶，突然亲切。</p><p>无脑填数就行。</p><h3 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="built_in">print</span>(<span class="built_in">pow</span>(<span class="number">101</span>, <span class="number">17</span>, <span class="number">22663</span>))</span><br></pre></td></tr></table></figure><h2 id="RSA-Starter-2"><a href="#RSA-Starter-2" class="headerlink" title="RSA Starter 2"></a>RSA Starter 2</h2><h3 id="Description-1"><a href="#Description-1" class="headerlink" title="Description"></a>Description</h3><p>RSA encryption is modular exponentiation of a message with an exponent <code>e</code> and a modulus <code>N</code> which is normally a product of two primes: <code>N = p * q</code>.</p><p>Together the exponent and modulus form an RSA “public key” <code>(N, e)</code>. The most common value for <code>e</code> is <code>0x10001</code> or <code>65537</code>.</p><p>“Encrypt” the number <code>12</code> using the exponent <code>e = 65537</code> and the primes <code>p = 17</code> and <code>q = 23</code>. What number do you get as the ciphertext?</p><h3 id="Analyze-1"><a href="#Analyze-1" class="headerlink" title="Analyze"></a>Analyze</h3><p>两个素数的乘积为模数。还是无脑填数。</p><h3 id="Code-1"><a href="#Code-1" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">b = <span class="number">12</span></span><br><span class="line">e = <span class="number">65537</span></span><br><span class="line">p, q = <span class="number">17</span>, <span class="number">23</span></span><br><span class="line">N = p * q</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">pow</span>(b, e, N))</span><br></pre></td></tr></table></figure><h2 id="RSA-Starter-3"><a href="#RSA-Starter-3" class="headerlink" title="RSA Starter 3"></a>RSA Starter 3</h2><h3 id="Description-2"><a href="#Description-2" class="headerlink" title="Description"></a>Description</h3><p>RSA relies on the difficulty of the factorisation of the modulus <code>N</code>. If the primes can be found then we can calculate the <a href="https://leimao.github.io/article/RSA-Algorithm/">Euler totient</a> of <code>N</code> and thus decrypt the ciphertext.</p><p>Given <code>N = p*q</code> and two primes:</p><figure class="highlight abnf"><table><tr><td class="code"><pre><span class="line"><span class="attribute">p</span> <span class="operator">=</span> <span class="number">857504083339712752489993810777</span></span><br><span class="line"><span class="attribute">q</span> <span class="operator">=</span> <span class="number">1029224947942998075080348647219</span></span><br></pre></td></tr></table></figure><p>What is the totient of <code>N</code>?</p><h3 id="Analyze-2"><a href="#Analyze-2" class="headerlink" title="Analyze"></a>Analyze</h3><p>欧拉方程：$φ(mn) = φ(m)φ(n)$</p><p>因为 p，q 都是素数，所以 $φ(p) = p - 1$ ，$φ(q) = q - 1$。</p><p>在这道题里面是这样</p><script type="math/tex; mode=display">\begin{align}φ(N) &= φ(p*q) \\\ &= φ(p)φ(q) \\\ &= (p-1)(q-1)\end{align}</script><h3 id="Code-2"><a href="#Code-2" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">p = <span class="number">857504083339712752489993810777</span></span><br><span class="line">q = <span class="number">1029224947942998075080348647219</span></span><br><span class="line">N = (p - <span class="number">1</span>) * (q - <span class="number">1</span>)</span><br><span class="line"><span class="built_in">print</span>(N)</span><br></pre></td></tr></table></figure><h2 id="RSA-Starter-4"><a href="#RSA-Starter-4" class="headerlink" title="RSA Starter 4"></a>RSA Starter 4</h2><h3 id="Description-3"><a href="#Description-3" class="headerlink" title="Description"></a>Description</h3><p>The private key <code>d</code> is used to decrypt ciphertexts created with the corresponding public key (it’s also used to “sign” a message but we’ll get to that later).</p><p>The private key is the secret piece of information or “trapdoor” which allows us to quickly invert the encryption function. If RSA is implemented well, if you do not have the private key the fastest way to decrypt the ciphertext is to first factorise the modulus.</p><p>In RSA the private key is the <a href="https://en.wikipedia.org/wiki/Modular_multiplicative_inverse">modular multiplicative inverse</a> of the exponent <code>e</code> modulo the totient of <code>N</code>.</p><p>Given the two primes:</p><figure class="highlight abnf"><table><tr><td class="code"><pre><span class="line"><span class="attribute">p</span> <span class="operator">=</span> <span class="number">857504083339712752489993810777</span></span><br><span class="line"><span class="attribute">q</span> <span class="operator">=</span> <span class="number">1029224947942998075080348647219</span></span><br></pre></td></tr></table></figure><p>and the exponent:</p><figure class="highlight abnf"><table><tr><td class="code"><pre><span class="line"><span class="attribute">e</span> <span class="operator">=</span> <span class="number">65537</span></span><br></pre></td></tr></table></figure><p>What is the private key <code>d</code>?</p><h3 id="Analyze-3"><a href="#Analyze-3" class="headerlink" title="Analyze"></a>Analyze</h3><p>对 e 求逆元。$d * e= 1 \mod N$。</p><p>第一次用这个库好像？</p><h3 id="Code-3"><a href="#Code-3" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> gmpy2</span><br><span class="line"></span><br><span class="line">p = <span class="number">857504083339712752489993810777</span></span><br><span class="line">q = <span class="number">1029224947942998075080348647219</span></span><br><span class="line">e = <span class="number">65537</span></span><br><span class="line">N = (p - <span class="number">1</span>) * (q - <span class="number">1</span>)</span><br><span class="line">d = gmpy2.invert(e, N)</span><br><span class="line"><span class="built_in">print</span>(d)</span><br></pre></td></tr></table></figure><h2 id="RSA-Starter-5"><a href="#RSA-Starter-5" class="headerlink" title="RSA Starter 5"></a>RSA Starter 5</h2><h3 id="Description-4"><a href="#Description-4" class="headerlink" title="Description"></a>Description</h3><p>I’ve encrypted a secret number for your eyes only using your public key parameters:</p><figure class="highlight abnf"><table><tr><td class="code"><pre><span class="line"><span class="attribute">N</span> <span class="operator">=</span> <span class="number">882564595536224140639625987659416029426239230804614613279163</span></span><br><span class="line"><span class="attribute">e</span> <span class="operator">=</span> <span class="number">65537</span></span><br></pre></td></tr></table></figure><p>Use the private key that you found for these parameters in the previous challenge to decrypt this ciphertext:</p><figure class="highlight abnf"><table><tr><td class="code"><pre><span class="line"><span class="attribute">c</span> <span class="operator">=</span> <span class="number">77578995801157823671636298847186723593814843845525223303932</span></span><br></pre></td></tr></table></figure><h3 id="Analyze-4"><a href="#Analyze-4" class="headerlink" title="Analyze"></a>Analyze</h3><p>和第一题没区别，无脑填数。</p><h3 id="Code-4"><a href="#Code-4" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">N = <span class="number">882564595536224140639625987659416029426239230804614613279163</span></span><br><span class="line">c = <span class="number">77578995801157823671636298847186723593814843845525223303932</span></span><br><span class="line">d = <span class="number">121832886702415731577073962957377780195510499965398469843281</span></span><br><span class="line">flag = <span class="built_in">pow</span>(c, d, N)</span><br><span class="line"><span class="built_in">print</span>(flag)</span><br></pre></td></tr></table></figure><h2 id="RSA-Starter-6"><a href="#RSA-Starter-6" class="headerlink" title="RSA Starter 6"></a>RSA Starter 6</h2><h3 id="Description-5"><a href="#Description-5" class="headerlink" title="Description"></a>Description</h3><p>How can you ensure that the person receiving your message knows that you wrote it?</p><p>You’ve been asked out on a date, and you want to send a message telling them that you’d love to go, however a jealous lover isn’t so happy about this.</p><p>When you send your message saying yes, your jealous lover intercepts the message and corrupts it so it now says no!</p><p>We can protect against these attacks by signing the message.</p><p>Imagine you write a message <code>M</code>. You encrypt this message with your <strong>friend’s public key</strong>: <code>C = Mᵉ⁰ mod N₀</code>.</p><p>To sign this message, you calculate the hash of the message: <code>H(M)</code> and “encrypt” this with <strong>your private key</strong>: <code>S = H(M)ᵈ¹ mod N₁</code>.</p><blockquote><p>In real cryptosystems, it’s <a href="https://crypto.stackexchange.com/a/12138">best practice to use separate keys</a> for encrypting and signing messages.</p></blockquote><p>Your friend can decrypt the message using <strong>their private key</strong>: <code>m = Cᵈ⁰ mod N₀</code>. Using your public key they calculate <code>s = Sᵉ¹ mod N₁</code>.</p><p>Now by computing <code>H(m)</code> and comparing it to <code>s</code>: <code>assert H(m) == s</code>, they can ensure that the message you sent them, is the message that they received!</p><p>Sign the flag <code>crypto&#123;Immut4ble_m3ssag1ng&#125;</code> using your private key and the SHA256 hash function.</p><h3 id="Analyze-5"><a href="#Analyze-5" class="headerlink" title="Analyze"></a>Analyze</h3><p>英文看得有点头大，得浅理一下逻辑。</p><blockquote><p>Alice 向 Bob 发送消息：</p><ol><li><p>用 Bob 的公钥加密得到 C</p></li><li><p>签名</p><blockquote><p>签名步骤</p><ol><li>求消息的哈希值 H</li><li>用 Alice 的私钥“加密”哈希值得到 S</li></ol></blockquote></li></ol><p>Bob 接收 Alice 的消息：</p><ol><li>用 Bob 的私钥解密得到 m</li><li>用 Alice 的公钥计算“解密”得到 s</li><li>计算消息的哈希值 H</li><li>比较 s 和 H，二者相等就能确定消息是真实的</li></ol></blockquote><p>签名是个蛮好玩的东西捏。</p><h3 id="Code-5"><a href="#Code-5" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> hashlib <span class="keyword">import</span> sha256</span><br><span class="line"></span><br><span class="line">N = <span class="number">15216583654836731327639981224133918855895948374072384050848479908982286890731769486609085918857664046075375253168955058743185664390273058074450390236774324903305663479046566232967297765731625328029814055635316002591227570271271445226094919864475407884459980489638001092788574811554149774028950310695112688723853763743238753349782508121985338746755237819373178699343135091783992299561827389745132880022259873387524273298850340648779897909381979714026837172003953221052431217940632552930880000919436507245150726543040714721553361063311954285289857582079880295199632757829525723874753306371990452491305564061051059885803</span></span><br><span class="line">d = <span class="number">11175901210643014262548222473449533091378848269490518850474399681690547281665059317155831692300453197335735728459259392366823302405685389586883670043744683993709123180805154631088513521456979317628012721881537154107239389466063136007337120599915456659758559300673444689263854921332185562706707573660658164991098457874495054854491474065039621922972671588299315846306069845169959451250821044417886630346229021305410340100401530146135418806544340908355106582089082980533651095594192031411679866134256418292249592135441145384466261279428795408721990564658703903787956958168449841491667690491585550160457893350536334242689</span></span><br><span class="line"></span><br><span class="line">flag = <span class="string">&quot;crypto&#123;Immut4ble_m3ssag1ng&#125;&quot;</span></span><br><span class="line">flag = flag.encode()</span><br><span class="line"><span class="built_in">hash</span> = sha256(flag)</span><br><span class="line"><span class="built_in">hash</span> = <span class="built_in">hash</span>.hexdigest()</span><br><span class="line"><span class="built_in">hash</span> = <span class="built_in">int</span>(<span class="built_in">hash</span>, <span class="number">16</span>)</span><br><span class="line">c = <span class="built_in">pow</span>(<span class="built_in">hash</span>, d, N)</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">hex</span>(c))</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;这个超快！&lt;/p&gt;
&lt;p&gt;我看谁不是速通（bushi&lt;/p&gt;
    
    </summary>
    
      <category term="学习" scheme="http://smilin9.com/categories/%E5%AD%A6%E4%B9%A0/"/>
    
    
      <category term="cryptohack" scheme="http://smilin9.com/tags/cryptohack/"/>
    
  </entry>
  
  <entry>
    <title>前三章补充</title>
    <link href="http://smilin9.com/2022/05/08/%E5%89%8D%E4%B8%89%E7%AB%A0%E8%A1%A5%E5%85%85/"/>
    <id>http://smilin9.com/2022/05/08/前三章补充/</id>
    <published>2022-05-08T07:29:00.000Z</published>
    <updated>2022-12-12T14:57:53.177Z</updated>
    
    <content type="html"><![CDATA[<p>之前竟然做错模块了？寄！</p><span id="more"></span><p>我真的谢。</p><p>7 号凌晨和面试师傅抱怨 Courses 第五章的 ECC 难学，师傅震惊：“你怎么去学 ECC 了？”，然后发现面试任务竟然是 Challenge 的那些章节，当时就心态大崩，我就说 ECC 怎么会是我现在可以染指的东西啊（麻。。</p><p>不过还好师傅把二面时间延迟到 10 号了，7 号调休 9 号满课，算下来其实也就多了 8 号的周日可以做题，所以 8 号我必早起！</p><p>这篇先补一下 Challenge 前三章没做的题，第五章后面再单独写吧。</p><h1 id="Introduction"><a href="#Introduction" class="headerlink" title="Introduction"></a>Introduction</h1><h2 id="Network-Attacks"><a href="#Network-Attacks" class="headerlink" title="Network Attacks"></a>Network Attacks</h2><h3 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h3><p>Several of the challenges are dynamic and require you to talk to our challenge servers over the network. This allows you to perform man-in-the-middle attacks on people trying to communicate, or directly attack a vulnerable service. To keep things consistent, our interactive servers always send and receive JSON objects.</p><p>Python makes such network communication easy with the <code>telnetlib</code> module. Conveniently, it’s part of Python’s standard library, so let’s use it for now.</p><p>For this challenge, connect to <code>socket.cryptohack.org</code> on port <code>11112</code>. Send a JSON object with the key <code>buy</code> and value <code>flag</code>.</p><p>The example script below contains the beginnings of a solution for you to modify, and you can reuse it for later challenges.</p><p>Connect at <code>nc socket.cryptohack.org 11112</code>.</p><h3 id="Analyze"><a href="#Analyze" class="headerlink" title="Analyze"></a>Analyze</h3><p>使用中间人攻击的方式获取 flag 。</p><p>使用 telnetlib 库对 socket.cryptohack.org 11112端口以  JSON 对象的方式进行请求。</p><p>题目说的很明确，就把 buy 的值改成 flag，运行代码就能出结果。</p><h3 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 部分代码</span></span><br><span class="line">request = &#123;</span><br><span class="line">    <span class="string">&quot;buy&quot;</span>: <span class="string">&quot;flag&quot;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h1 id="General"><a href="#General" class="headerlink" title="General"></a>General</h1><h2 id="ENCODING-Encoding-Challenge"><a href="#ENCODING-Encoding-Challenge" class="headerlink" title="ENCODING_Encoding Challenge"></a>ENCODING_Encoding Challenge</h2><h3 id="Description-1"><a href="#Description-1" class="headerlink" title="Description"></a>Description</h3><p>Now you’ve got the hang of the various encodings you’ll be encountering, let’s have a look at automating it.</p><p>Can you pass all 100 levels to get the flag?</p><p>The <em>13377.py</em> file attached below is the source code for what’s running on the server. The <em>pwntools_example.py</em> file provides the start of a solution using the incredibly convenient pwntools library. which we recommend. If you’d prefer to use Python’s in-built telnetlib, <em>telnetlib_example.py</em> is also provided.</p><p>For more information about connecting to interactive challenges, see the <a href="https://cryptohack.org/faq#netcat">FAQ</a>. Feel free to skip ahead to the cryptography if you aren’t in the mood for a coding challenge!</p><p>Connect at <code>nc socket.cryptohack.org 13377</code>.</p><h3 id="Analyze-1"><a href="#Analyze-1" class="headerlink" title="Analyze"></a>Analyze</h3><p>刚开始看题是真没搞明白他要干啥，甚至以为这不是密码题。。（可能我阅读能力有问题？</p><p>阅读服务端的代码，第一次连接服务器会返回编码方式以及编码后的字符串，这时候需要提交解码后的字符串，正确解码后服务器会发来下一个。100 次之后服务器主动终止连接，解码之后得到的就是 flag。</p><p>解码函数看着他的加密代码倒是蛮容易写的，但是确实不喜欢做这类题。</p><h3 id="Code-1"><a href="#Code-1" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> codecs</span><br><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">from</span> Crypto.Util.number <span class="keyword">import</span> *</span><br><span class="line"><span class="keyword">import</span> json</span><br><span class="line"></span><br><span class="line">r = remote(<span class="string">&#x27;socket.cryptohack.org&#x27;</span>, <span class="number">13377</span>, level=<span class="string">&#x27;debug&#x27;</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">json_recv</span>() -&gt; <span class="built_in">dict</span>:</span><br><span class="line">    line = r.recvline()</span><br><span class="line">    <span class="keyword">return</span> json.loads(line.decode())</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">json_send</span>(<span class="params">hsh: <span class="built_in">dict</span></span>) -&gt; <span class="literal">None</span>:</span><br><span class="line">    request = json.dumps(hsh).encode()</span><br><span class="line">    r.sendline(request)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decode</span>(<span class="params">encoded: <span class="built_in">str</span>, <span class="built_in">type</span>: <span class="built_in">str</span></span>) -&gt; <span class="built_in">str</span>:</span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">type</span> == <span class="string">&quot;base64&quot;</span>:</span><br><span class="line">        <span class="keyword">return</span> base64.b64decode(encoded).decode()</span><br><span class="line">    <span class="keyword">elif</span> <span class="built_in">type</span> == <span class="string">&quot;hex&quot;</span>:</span><br><span class="line">        <span class="keyword">return</span> codecs.decode(encoded, <span class="string">&#x27;hex&#x27;</span>).decode()</span><br><span class="line">    <span class="keyword">elif</span> <span class="built_in">type</span> == <span class="string">&quot;rot13&quot;</span>:</span><br><span class="line">        <span class="keyword">return</span> codecs.decode(encoded, <span class="string">&#x27;rot_13&#x27;</span>)</span><br><span class="line">    <span class="keyword">elif</span> <span class="built_in">type</span> == <span class="string">&quot;bigint&quot;</span>:</span><br><span class="line">        <span class="keyword">return</span> long_to_bytes(<span class="built_in">int</span>(encoded, <span class="number">16</span>)).decode()</span><br><span class="line">    <span class="keyword">elif</span> <span class="built_in">type</span> == <span class="string">&quot;utf-8&quot;</span>:</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;&quot;</span>.join(<span class="built_in">chr</span>(i) <span class="keyword">for</span> i <span class="keyword">in</span> encoded)</span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;Unknown encoding&quot;</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># 第一次接收</span></span><br><span class="line">received = json_recv()</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">100</span>):</span><br><span class="line">    plain_text = decode(received[<span class="string">&quot;encoded&quot;</span>], received[<span class="string">&quot;type&quot;</span>])</span><br><span class="line">    to_send = &#123;</span><br><span class="line">        <span class="string">&quot;decoded&quot;</span>: plain_text</span><br><span class="line">    &#125;</span><br><span class="line">    json_send(to_send)</span><br><span class="line">    received = json_recv()</span><br></pre></td></tr></table></figure><h2 id="XOR-Lemur-XOR"><a href="#XOR-Lemur-XOR" class="headerlink" title="XOR_Lemur XOR"></a>XOR_Lemur XOR</h2><h3 id="Description-2"><a href="#Description-2" class="headerlink" title="Description"></a>Description</h3><p>I’ve hidden two cool images by XOR with the same secret key so you can’t see them!</p><h3 id="Analyze-2"><a href="#Analyze-2" class="headerlink" title="Analyze"></a>Analyze</h3><p>题目描述倒是挺短。</p><p>直接二进制异或不行，然后试试像素点异或。</p><p>对图片操作很陌生诶。还是菜。</p><h3 id="Code-2"><a href="#Code-2" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> PIL <span class="keyword">import</span> Image</span><br><span class="line"></span><br><span class="line">flagImg = Image.<span class="built_in">open</span>(<span class="string">&#x27;D:/files/codeFiles/pyCode/cryptohack/Challenge/补充/flag.png&#x27;</span>)</span><br><span class="line">flag = flagImg.load()</span><br><span class="line"></span><br><span class="line">lemurImg = Image.<span class="built_in">open</span>(<span class="string">&#x27;D:/files/codeFiles/pyCode/cryptohack/Challenge/补充/lemur.png&#x27;</span>)</span><br><span class="line">lemur = lemurImg.load()</span><br><span class="line">width, height = flagImg.size</span><br><span class="line"></span><br><span class="line">newImg = Image.new(<span class="string">&#x27;RGB&#x27;</span>, (width, height))</span><br><span class="line">new = newImg.load()</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(width):</span><br><span class="line">    <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(height):</span><br><span class="line">        r1, g1, b1 = flag[i, j]</span><br><span class="line">        r2, g2, b2 = lemur[i, j]</span><br><span class="line">        new[i, j] = (r1 ^ r2, g1 ^ g2, b1 ^ b2)</span><br><span class="line"></span><br><span class="line">newImg.save(<span class="string">&#x27;D:/files/codeFiles/pyCode/cryptohack/Challenge/补充/xorimage.png&#x27;</span>)</span><br></pre></td></tr></table></figure><h2 id="DATA-FORMATS-Privacy-Enhanced-Mail"><a href="#DATA-FORMATS-Privacy-Enhanced-Mail" class="headerlink" title="DATA FORMATS_Privacy-Enhanced Mail?"></a>DATA FORMATS_Privacy-Enhanced Mail?</h2><h3 id="Description-3"><a href="#Description-3" class="headerlink" title="Description"></a>Description</h3><p>As we’ve seen in the encoding section, cryptography involves dealing with data in a wide variety of formats: big integers, raw bytes, hex strings and more. A few structured formats have been standardised to help send and receive cryptographic data. It helps to be able to recognise and manipulate these common data formats.</p><p>PEM is a popular format for sending keys, certificates, and other cryptographic material. It looks like:</p><figure class="highlight jboss-cli"><table><tr><td class="code"><pre><span class="line"><span class="params">-----BEGIN</span> RSA PUBLIC KEY<span class="params">-----</span></span><br><span class="line">MIIBCgKC.<span class="string">..</span> *<span class="params">(a whole bunch of base64)</span>*</span><br><span class="line"><span class="params">-----END</span> RSA PUBLIC KEY<span class="params">-----</span></span><br></pre></td></tr></table></figure><p>It wraps base64-encoded data by a one-line header and footer to indicate how to parse the data within. Perhaps unexpectedly, it’s important for there to be the correct number of hyphens in the header and footer, otherwise cryptographic tools won’t be able to recognise the file.</p><p>The data that gets base64-encoded is DER-encoded ASN.1 values. Confused? <a href="https://www.cryptologie.net/article/260/asn1-vs-der-vs-pem-vs-x509-vs-pkcs7-vs/">Here</a> is more information about what these acronyms mean but the complexity is there for historical reasons and going too deep into the details may drive you insane.</p><p>Extract the private key <em>d</em> as a decimal integer from this PEM-formatted RSA key.</p><blockquote><p>There are two main approaches for solving this challenge. The data in the certificate can be read with the openssl command line tool, or in Python using PyCryptodome. We recommend using PyCryptodome: first import the RSA module with <code>from Crypto.PublicKey import RSA</code> and you can read the key data using <code>RSA.importKey()</code>.</p></blockquote><h3 id="Analyze-3"><a href="#Analyze-3" class="headerlink" title="Analyze"></a>Analyze</h3><p>.pem 文件诶，看起来好酷的样子。</p><p>用给出的库和函数转换一下直接出。</p><h3 id="Code-3"><a href="#Code-3" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto.PublicKey <span class="keyword">import</span> RSA</span><br><span class="line"></span><br><span class="line">c = <span class="built_in">open</span>(<span class="string">r&quot;./privacy_enhanced_mail.pem&quot;</span>).read()</span><br><span class="line">p = RSA.import_key(c)</span><br><span class="line"><span class="built_in">print</span>(p.d)</span><br></pre></td></tr></table></figure><h2 id="DATA-FORMATS-CERTainly-not"><a href="#DATA-FORMATS-CERTainly-not" class="headerlink" title="DATA FORMATS_CERTainly not"></a>DATA FORMATS_CERTainly not</h2><h3 id="Description-4"><a href="#Description-4" class="headerlink" title="Description"></a>Description</h3><p>As mentioned in the previous challenge, PEM is just a nice wrapper above DER encoded ASN.1. In some cases you may come across DER files directly; for instance many Windows utilities prefer to work with DER files by default. However, other tools expect PEM format and have difficulty importing a DER file, so it’s good to know how to convert one format to another.</p><p>An SSL certificate is a crucial part of the modern web, binding a cryptographic key to details about an organisation. We’ll cover more about these and PKI in the TLS category. Presented here is a DER-encoded x509 RSA certificate. Find the modulus of the certificate, giving your answer as a decimal.</p><h3 id="Analyze-4"><a href="#Analyze-4" class="headerlink" title="Analyze"></a>Analyze</h3><p>.der 文件，看起来依然很牛。</p><p>和上一题基本就改了个文件名。</p><h3 id="Code-4"><a href="#Code-4" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto.PublicKey <span class="keyword">import</span> RSA</span><br><span class="line"></span><br><span class="line">c = <span class="built_in">open</span>(<span class="string">r&quot;./CERTainly not_2048b-rsa-example-cert.der&quot;</span>, <span class="string">&#x27;rb&#x27;</span>).read()</span><br><span class="line">p = RSA.import_key(c)</span><br><span class="line"><span class="built_in">print</span>(p.n)</span><br></pre></td></tr></table></figure><h2 id="DATA-FORMATS-SSH-Keys"><a href="#DATA-FORMATS-SSH-Keys" class="headerlink" title="DATA FORMATS_SSH Keys"></a>DATA FORMATS_SSH Keys</h2><h3 id="Description-5"><a href="#Description-5" class="headerlink" title="Description"></a>Description</h3><p>Secure Shell Protocol (SSH) is a network protocol that uses cryptography to establish a secure channel over an insecure network (i.e. the internet). SSH enables developers and system administrators to run commands on servers from the other side of the world, without their password being sniffed or data being stolen. It is therefore critical to the security of the web.</p><p>In the old days, system administrators used to logon to their servers using telnet. This works similarly to our interactive challenges that involve connecting to <code>socket.cryptohack.org</code> - data is sent to a remote server, which performs actions based on what is sent. There is no transport encryption, so anyone listening in on the network (such as the WiFi access point owner, your ISP, or the NSA) can see all the telnet traffic.</p><p>As the internet became increasingly hostile, people realised the need for both authentication and encryption for administrative network traffic. SSH, first released in 1995, achieves these goals and much more, with advanced functionality built into the software like port forwarding, X11 forwarding, and SFTP (Secure File Transfer Protocol). SSH uses a client-server architecture, meaning the server runs SSH as a service daemon which is always online and waiting to receive connections, and the user runs an SSH client to make a connection to it.</p><p>Most commonly, SSH is configured to use public-private key pairs for authentication. On the server, a copy of the user’s public key is stored. The user’s private key is stored locally on their laptop.</p><p>Now let’s say Bruce wants to connect as his user account <code>bschneier</code> to his server <code>bruces-server</code>. From his laptop he runs <code>ssh bschneier@bruces-server</code>. His SSH client opens a connection to the server on port 22 where the SSH daemon listens. First, the ciphers that will be used are agreed upon, then a session key to encrypt the connection is established using Diffie-Hellman Key exchange, but we won’t go into the details on that here. Then, the server sends a random challenge message encrypted with Bruce’s public key. Bruce uses his private key to decrypt the challenge and send a hash of the random challenge message back, proving that he owns the correct private key and he therefore authenticates himself to the server as <code>bschneier</code>. Now, the server gives Bruce a shell to run commands. If public-private key cryptography doesn’t make sense to you yet, don’t worry - we’ll cover it extensively in the RSA category.</p><p>An SSH private key is stored in the PEM format, which we discussed in the “Privacy-Enhanced Mail” challenge. So it looks like this and is stored on Bruce’s laptop at <code>/home/bschneier/.ssh/id_rsa</code>:</p><figure class="highlight jboss-cli"><table><tr><td class="code"><pre><span class="line"><span class="params">-----BEGIN</span> RSA PRIVATE KEY<span class="params">-----</span></span><br><span class="line">MIIBCgKC.<span class="string">..</span> *<span class="params">(a whole bunch of base64)</span>*</span><br><span class="line"><span class="params">-----END</span> RSA PRIVATE KEY<span class="params">-----</span></span><br></pre></td></tr></table></figure><p>SSH public keys, however, use a different format:</p><figure class="highlight awk"><table><tr><td class="code"><pre><span class="line">ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCtPLqba+GFvDHdFVs1Vvdk56cKqqw5cdomlu034666UsoFIqkig8H5kNsNefSpaR<span class="regexp">/iU7G0ZKCiWRRuAbTsuHN+Cz526XhQvzgKTBkTGYXdF/</span>WdG<span class="regexp">/6/um</span>ou3Z0+wJvTZgvEmeEclvitBrPZkzhAK1M5ypgNR4p8scJplTgSSb84Ckqul<span class="regexp">/Dj/</span>Sh+fwo6sU3S3j92qc27BVGChpQiGwjjut4CkHauzQA<span class="regexp">/gKCBIiLyzoFcLEHhjOBOEErnvrRPWCIAJhALkwV2rUbD4g1IWa7QI2q3nB0nlnjPnjjwaR7TpH4gy2NSIYNDdC1PZ8reBaFnGTXgzhQ2t0ROBNb+ZDgH8Fy+KTG+gEakpu20bRqB86NN6frDLOkZ9x3w32tJtqqrJTALy4Oi3MW0XPO61UBT133VNqAbNYGE2gx+mXBVOezbsY46C/</span>V2fmxBJJKY<span class="regexp">/SFNs8wOVOHKwqRH0GI5VsG1YZClX3fqk8GDJYREaoyoL3HKQt1Ue/</span>ZW7TlPRYzAoIB62C0= bschneier@facts</span><br></pre></td></tr></table></figure><p>This format makes it easier for these public keys to be added as lines to the file <code>/home/bschneier/.ssh/authorized_keys</code> on the server. Adding the public key to this file allows the corresponding private key to be used to authenticate on the server.</p><p>The <code>ssh-keygen</code> command is used to produce these public-private keypairs.</p><p>Extract the modulus <em>n</em> as a decimal integer from Bruce’s SSH public key.</p><h3 id="Analyze-5"><a href="#Analyze-5" class="headerlink" title="Analyze"></a>Analyze</h3><p>.pub 后缀更酷了。</p><p>不过和第一题解法没区别，只能说函数真的强大。</p><h3 id="Code-5"><a href="#Code-5" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto.PublicKey <span class="keyword">import</span> RSA</span><br><span class="line"></span><br><span class="line">c = <span class="built_in">open</span>(<span class="string">r&quot;./SSH Keys_bruce_rsa.pub&quot;</span>).read()</span><br><span class="line">p = RSA.import_key(c)</span><br><span class="line"><span class="built_in">print</span>(p.n)</span><br></pre></td></tr></table></figure><h2 id="DATA-FORMATS-Transparency"><a href="#DATA-FORMATS-Transparency" class="headerlink" title="DATA FORMATS_Transparency"></a>DATA FORMATS_Transparency</h2><h3 id="Description-6"><a href="#Description-6" class="headerlink" title="Description"></a>Description</h3><p>When you connect to a website over HTTPS, the first TLS message sent by the server is the ServerHello containing the server TLS certificate. Your browser verifies that the TLS certificate is valid, and if not, will terminate the TLS handshake. Verification includes ensuring that:</p><p>- the name on the certificate matches the domain</p><p>- the certificate has not expired</p><p>- the certificate is ultimately signed (via a “chain of trust”) by a root key of a Certificate Authority (CA) that’s trusted by your browser or operating system</p><p>Since CAs have the power to sign any certificate, the security of the internet depends upon these organisations to issue TLS certificates to the correct people: they must only issue certificates to the real domain owners. However with Windows trusting root certificates from over 100 organisations by default, there’s a number of opportunities for hackers, politics, or incompetence to break the whole model. If you could trick just a single CA to issue you a certificate for microsoft.com, you could use the corresponding private key to sign malware and bypass trust controls on Windows. CAs are strongly incentivised to be careful since their business depends upon people trusting them, however in practice they have failed several times.</p><p>In 2011 <a href="https://arstechnica.com/information-technology/2011/03/independent-iranian-hacker-claims-responsibility-for-comodo-hack/">Comodo CA was compromised</a> and the hacker was able to issue certificates for Gmail and other services. In 2016, <a href="https://security.googleblog.com/2015/10/sustaining-digital-certificate-security.html">Symantec was found</a> to have issued over 150 certificates without the domain owner’s knowledge, as well as 2400 certificates for domains that were never registered.</p><p>Due to such events, together with the fact that fraudulent certificates can take a long time to be discovered, since 2018 Certificate Transparency has been enforced by Google Chrome. Every CA must publish all certificates that they issue to a log, which anyone can search.</p><p>Attached is an RSA public key in PEM format. Find the subdomain of cryptohack.org which uses these parameters in its TLS certificate, and visit that subdomain to obtain the flag.</p><h3 id="Analyze-6"><a href="#Analyze-6" class="headerlink" title="Analyze"></a>Analyze</h3><p>这题怎么说呢，一言难尽。</p><p>倒是能解出来 n，但是怎么找到包含 n 的证书对应的域名呢，搜了很久也没找到。</p><p>最后是直接去爆破，找到 url 里包含 flag 的子域名，访问得到 flag。</p><p>也可以用 <a href="https://crt.sh/">crt.sh</a> 搜指纹，查日志记录，不过也没用到公钥。</p><p>最后还是不知道怎么用公钥推域名，怪捏。</p><h1 id="Mathematics"><a href="#Mathematics" class="headerlink" title="Mathematics"></a>Mathematics</h1><p>虽然之前做数学做了很久，不过值得欣慰的是 Challenge 第三章第一部分全都做完了。具体<a href="http://smilin9.com/2022/05/03/Modular%20Arithmetic/">在这里</a> 。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;之前竟然做错模块了？寄！&lt;/p&gt;
    
    </summary>
    
      <category term="学习" scheme="http://smilin9.com/categories/%E5%AD%A6%E4%B9%A0/"/>
    
    
      <category term="cryptohack" scheme="http://smilin9.com/tags/cryptohack/"/>
    
  </entry>
  
  <entry>
    <title>Symmetric Ciphers1</title>
    <link href="http://smilin9.com/2022/05/05/Symmetric%20Ciphers1/"/>
    <id>http://smilin9.com/2022/05/05/Symmetric Ciphers1/</id>
    <published>2022-05-05T15:42:00.000Z</published>
    <updated>2022-12-12T14:57:53.173Z</updated>
    
    <content type="html"><![CDATA[<p>第三章好像是做的最迷的</p><span id="more"></span><p>虽然只需要做 ”How AES Works” 部分。但是——</p><p>刚开始第三章：还以为会越来越难，没想到做完数论就柳暗花明了？</p><p>第三章最后一题：什么东西啊这是，这怎么比数论那块还复杂。。</p><h1 id="How-AES-Works"><a href="#How-AES-Works" class="headerlink" title="How AES Works"></a>How AES Works</h1><h2 id="Keyed-Permutations"><a href="#Keyed-Permutations" class="headerlink" title="Keyed Permutations"></a>Keyed Permutations</h2><h3 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h3><p>AES, like all good block ciphers, performs a “keyed permutation”. This means that it maps every possible input block to a unique output block, with a key determining which permutation to perform.</p><blockquote><p>A “block” just refers to a fixed number of bits or bytes, which may represent any kind of data. AES processes a block and outputs another block. We’ll be specifically talking the variant of AES which works on 128 bit (16 byte) blocks and a 128 bit key, known as AES-128.</p></blockquote><p>Using the same key, the permutation can be performed in reverse, mapping the output block back to the original input block. It is important that there is a one-to-one correspondence between input and output blocks, otherwise we wouldn’t be able to rely on the ciphertext to decrypt back to the same plaintext we started with.</p><p>What is the mathematical term for a one-to-one correspondence?</p><h3 id="Analyze"><a href="#Analyze" class="headerlink" title="Analyze"></a>Analyze</h3><p>喔这题简单，我不知道但 Google 知道，浅搜一下”一一对应的数学术语“，知道叫双射函数，浅浅上个百科，就知道英语咯。</p><h2 id="Resisting-Bruteforce"><a href="#Resisting-Bruteforce" class="headerlink" title="Resisting Bruteforce"></a>Resisting Bruteforce</h2><h3 id="Description-1"><a href="#Description-1" class="headerlink" title="Description"></a>Description</h3><p>If a block cipher is secure, there should be no way for an attacker to distinguish the output of AES from a <a href="https://en.wikipedia.org/wiki/Pseudorandom_permutation">random permutation</a> of bits. Furthermore, there should be no better way to undo the permutation than simply bruteforcing every possible key. That’s why academics consider a cipher theoretically “broken” if they can find an attack that takes fewer steps to perform than bruteforcing the key, even if that attack is practically infeasible.</p><blockquote><p>How difficult is it to bruteforce a 128-bit keyspace? <a href="https://crypto.stackexchange.com/a/48669">Somebody estimated</a> that if you turned the power of the entire Bitcoin mining network against an AES-128 key, it would take over a hundred times the age of the universe to crack the key.</p></blockquote><p>It turns out that there is <a href="https://en.wikipedia.org/wiki/Biclique_attack">an attack</a> on AES that’s better than bruteforce, but only slightly – it lowers the security level of AES-128 down to 126.1 bits, and hasn’t been improved on for over 8 years. Given the large “security margin” provided by 128 bits, and the lack of improvements despite extensive study, it’s not considered a credible risk to the security of AES. But yes, in a very narrow sense, it “breaks” AES.</p><p>Finally, while quantum computers have the potential to completely break popular public-key cryptosystems like RSA via <a href="https://en.wikipedia.org/wiki/Shor&#39;s_algorithm">Shor’s algorithm</a>, they are thought to only cut in half the security level of symmetric cryptosystems via <a href="https://en.wikipedia.org/wiki/Grover&#39;s_algorithm">Grover’s algorithm</a>. This is one reason why people recommend using AES-256, despite it being less performant, as it would still provide a very adequate 128 bits of security in a quantum future.</p><p>What is the name for the best single-key attack against AES?</p><h3 id="Analyze-1"><a href="#Analyze-1" class="headerlink" title="Analyze"></a>Analyze</h3><p>虽然但是，依然去查了 Google，靠谱！</p><p>不过发现网上搜 biclique 的结果居然不是很多，我打开方式有问题吗是，后面再看看。</p><h2 id="Structure-of-AES"><a href="#Structure-of-AES" class="headerlink" title="Structure of AES"></a>Structure of AES</h2><h3 id="Description-2"><a href="#Description-2" class="headerlink" title="Description"></a>Description</h3><p>To achieve a keyed permutation that is infeasible to invert without the key, AES applies a large number of ad-hoc mixing operations on the input. This is in stark contrast to public-key cryptosystems like RSA, which are based on elegant individual mathematical problems. AES is much less elegant, but it’s very fast.</p><p>At a high level, AES-128 begins with a “key schedule” and then runs 10 rounds over a state. The starting state is just the plaintext block that we want to encrypt, represented as a 4x4 matrix of bytes. Over the course of the 10 rounds, the state is repeatedly modified by a number of invertible transformations.</p><blockquote><p>Each transformation step has a defined purpose based on theoretical properties of secure ciphers established by Claude Shannon in the 1940s. We’ll look closer at each of these in the following challenges.</p></blockquote><p>Here’s an overview of the phases of AES encryption:</p><p><img src="https://cryptohack.org/static/img/aes/Structure.png" alt="diagram showing AES rounds"></p><ol><li><strong>KeyExpansion</strong> or Key Schedule</li></ol><p> From the 128 bit key, 11 separate 128 bit “round keys” are derived: one to be used in each AddRoundKey step.</p><ol><li><strong>Initial key addition</strong></li></ol><p> <em>AddRoundKey</em> - the bytes of the first round key are XOR’d with the bytes of the state.</p><ol><li><strong>Round</strong> - this phase is looped 10 times, for 9 main rounds plus one “final round”</li></ol><p>     a) <em>SubBytes</em> - each byte of the state is substituted for a different byte according to a lookup table (“S-box”).</p><p>​     b) <em>ShiftRows</em> - the last three rows of the state matrix are transposed—shifted over a column or two or three.</p><p>​     c) <em>MixColumns</em> - matrix multiplication is performed on the columns of the state, combining the four bytes in each column. This is skipped in the final round.</p><p>​     d) <em>AddRoundKey</em> - the bytes of the current round key are XOR’d with the bytes of the state.</p><p>Included is a <code>bytes2matrix</code> function for converting our initial plaintext block into a state matrix. Write a <code>matrix2bytes</code> function to turn that matrix back into bytes, and submit the resulting plaintext as the flag.</p><h3 id="Analyze-2"><a href="#Analyze-2" class="headerlink" title="Analyze"></a>Analyze</h3><p>这题我会！</p><p>补全 matrix2bytes()，直接用 sum() 把矩阵压缩成一维列表，然后转字节输出。</p><p>补全函数的题比自己写代码的简单多了（bushi</p><h3 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">bytes2matrix</span>(<span class="params">text</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot; Converts a 16-byte array into a 4x4 matrix.  &quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">return</span> [<span class="built_in">list</span>(text[i:i+<span class="number">4</span>]) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="built_in">len</span>(text), <span class="number">4</span>)]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">matrix2bytes</span>(<span class="params">matrix</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot; Converts a 4x4 matrix into a 16-byte array.  &quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">bytes</span>(<span class="built_in">sum</span>(matrix, []))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">matrix = [</span><br><span class="line">    [<span class="number">99</span>, <span class="number">114</span>, <span class="number">121</span>, <span class="number">112</span>],</span><br><span class="line">    [<span class="number">116</span>, <span class="number">111</span>, <span class="number">123</span>, <span class="number">105</span>],</span><br><span class="line">    [<span class="number">110</span>, <span class="number">109</span>, <span class="number">97</span>, <span class="number">116</span>],</span><br><span class="line">    [<span class="number">114</span>, <span class="number">105</span>, <span class="number">120</span>, <span class="number">125</span>],</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(matrix2bytes(matrix))</span><br></pre></td></tr></table></figure><h3 id="SumUp"><a href="#SumUp" class="headerlink" title="SumUp"></a>SumUp</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># function</span></span><br><span class="line"><span class="built_in">sum</span>()  <span class="comment"># 把迭代对象里的每一个元素相加。（当元素是列表，就有压平的效果咯）</span></span><br></pre></td></tr></table></figure><h2 id="Round-Keys"><a href="#Round-Keys" class="headerlink" title="Round Keys"></a>Round Keys</h2><h3 id="Description-3"><a href="#Description-3" class="headerlink" title="Description"></a>Description</h3><p>We’re going to skip over the finer details of the <strong>KeyExpansion</strong> phase for now. The main point is that it takes in our 16 byte key and produces 11 4x4 matrices called “round keys” derived from our initial key. These round keys allow AES to get extra mileage out of the single key that we provided.</p><p>The <strong>initial key addition</strong> phase, which is next, has a single <em>AddRoundKey</em> step. The <em>AddRoundKey</em> step is straightforward: it XORs the current state with the current round key.</p><p><img src="https://cryptohack.org/static/img/aes/AddRoundKey.png" alt="diagram showing AddRoundKey"></p><p><em>AddRoundKey</em> also occurs as the final step of each round. <em>AddRoundKey</em> is what makes AES a “keyed permutation” rather than just a permutation. It’s the only part of AES where the key is mixed into the state, but is crucial for determining the permutation that occurs.</p><p>As you’ve seen in previous challenges, XOR is an easily invertible operation if you know the key, but tough to undo if you don’t. Now imagine trying to recover plaintext which has been XOR’d with 11 different keys, and heavily jumbled between each XOR operation with a series of substitution and transposition ciphers. That’s kinda what AES does! And we’ll see just how effective the jumbling is in the next few challenges.</p><p>Complete the <code>add_round_key</code> function, then use the <code>matrix2bytes</code> function to get your next flag.</p><h3 id="Analyze-3"><a href="#Analyze-3" class="headerlink" title="Analyze"></a>Analyze</h3><p>遇到异或就搬 pwn.xor()！</p><p>明文经过了 11 个不同的密钥进行异或，再异或回去就可以得到原文。</p><p>返回异或值就 ok。</p><p>感觉异或还是蛮有意思的。</p><h3 id="Code-1"><a href="#Code-1" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> xor</span><br><span class="line">state = [</span><br><span class="line">    [<span class="number">206</span>, <span class="number">243</span>, <span class="number">61</span>, <span class="number">34</span>],</span><br><span class="line">    [<span class="number">171</span>, <span class="number">11</span>, <span class="number">93</span>, <span class="number">31</span>],</span><br><span class="line">    [<span class="number">16</span>, <span class="number">200</span>, <span class="number">91</span>, <span class="number">108</span>],</span><br><span class="line">    [<span class="number">150</span>, <span class="number">3</span>, <span class="number">194</span>, <span class="number">51</span>],</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line">round_key = [</span><br><span class="line">    [<span class="number">173</span>, <span class="number">129</span>, <span class="number">68</span>, <span class="number">82</span>],</span><br><span class="line">    [<span class="number">223</span>, <span class="number">100</span>, <span class="number">38</span>, <span class="number">109</span>],</span><br><span class="line">    [<span class="number">32</span>, <span class="number">189</span>, <span class="number">53</span>, <span class="number">8</span>],</span><br><span class="line">    [<span class="number">253</span>, <span class="number">48</span>, <span class="number">187</span>, <span class="number">78</span>],</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">add_round_key</span>(<span class="params">s, k</span>):</span><br><span class="line">    <span class="keyword">return</span> xor(s, k)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(add_round_key(state, round_key))</span><br></pre></td></tr></table></figure><h2 id="Confusion-through-Substitution"><a href="#Confusion-through-Substitution" class="headerlink" title="Confusion through Substitution"></a>Confusion through Substitution</h2><h3 id="Description-4"><a href="#Description-4" class="headerlink" title="Description"></a>Description</h3><p>The first step of each AES round is <em>SubBytes</em>. This involves taking each byte of the state matrix and substituting it for a different byte in a preset 16x16 lookup table. The lookup table is called a “Substitution box” or “S-box” for short, and can be perplexing at first sight. Let’s break it down.</p><p><img src="https://cryptohack.org/static/img/aes/Substitution.png" alt="diagram showing Substitution"></p><p>In 1945 American mathematician Claude Shannon published a groundbreaking paper on Information Theory. It identified “confusion” as an essential property of a secure cipher. “Confusion” means that the relationship between the ciphertext and the key should be as complex as possible. Given just a ciphertext, there should be no way to learn anything about the key.</p><p>If a cipher has poor confusion, it is possible to express a relationship between ciphertext, key, and plaintext as a linear function. For instance, in a Caesar cipher, <code>ciphertext = plaintext + key</code>. That’s an obvious relation, which is easy to reverse. More complicated linear transformations can be solved using techniques like Gaussian elimination. Even low-degree polynomials, e.g. an equation like <code>x^4 + 51x^3 + x</code>, can be solved efficiently using <a href="https://math.stackexchange.com/a/1078515">algebraic methods</a>. However, the higher the degree of a polynomial, generally the harder it becomes to solve – it can only be approximated by a larger and larger amount of linear functions.</p><p>The main purpose of the S-box is to transform the input in a way that is resistant to being approximated by linear functions. S-boxes are aiming for high <em>non-linearity</em>, and while AES’s one is not perfect, it’s pretty close. The fast lookup in an S-box is a shortcut for performing a very nonlinear function on the input bytes. This function involves taking the modular inverse in the <a href="https://www.samiam.org/galois.html">Galois field 2**8</a> and then applying an affine transformation which has been tweaked for maximum confusion. The simplest way to express the function is through the following high-degree polynomial:</p><p><img src="https://cryptohack.org/static/img/aes/SBoxEq.png" alt="diagram showing S-Box equation"></p><p>To make the S-box, the function has been calculated on all input values from 0x00 to 0xff and the outputs put in the lookup table.</p><p>Implement <code>sub_bytes</code>, send the state matrix through the inverse S-box and then convert it to bytes to get the flag.</p><h3 id="Analyze-4"><a href="#Analyze-4" class="headerlink" title="Analyze"></a>Analyze</h3><p>意思就是让补全 sub_bytes 函数，然后转换成字节得到 flag。</p><p>其实 state 里面的存的是它每个位置上本来的数据在查找库 sbox 中的序号，所以遍历 state，按序号取出对应的原数据，然后返回字节就好咯。</p><h3 id="Code-2"><a href="#Code-2" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 写法一</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sub_bytes</span>(<span class="params">s, sbox=s_box</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">            s[i][j] = sbox[s[i][j]]</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">bytes</span>(<span class="built_in">sum</span>(s, []))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(sub_bytes(state, sbox=inv_s_box))</span><br><span class="line"></span><br><span class="line"><span class="comment"># 写法二</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">matrix2bytes</span>(<span class="params">matrix</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot; Converts a 4x4 matrix into a 16-byte array.  &quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">bytes</span>(<span class="built_in">sum</span>(matrix, []))</span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sub_bytes</span>(<span class="params">s, sbox=s_box</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">            s[i][j] = sbox[s[i][j]]</span><br><span class="line">    <span class="keyword">return</span> s</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(matrix2bytes(sub_bytes(state, sbox=inv_s_box)))</span><br></pre></td></tr></table></figure><h3 id="SumUp-1"><a href="#SumUp-1" class="headerlink" title="SumUp"></a>SumUp</h3><p>两种写法怎么说呢，第一种更简洁明了，看起来好像也更优雅。</p><p>第二种虽然搬过来了 matrix2bytes() 函数（也可以不搬函数直接一行搞定，不过读起来费劲点），看起来更繁琐，不过这种写法更不容易吃亏（在最后一题已经深刻体会过了）。所以本来是喜欢第一种写法的，做完最后一题之后还是喜欢第二种了。</p><p>（呜呜呜我也不想被钓啊，可是它解题更好用诶）。</p><h2 id="Diffusion-through-Permutation"><a href="#Diffusion-through-Permutation" class="headerlink" title="Diffusion through Permutation"></a>Diffusion through Permutation</h2><h3 id="Description-5"><a href="#Description-5" class="headerlink" title="Description"></a>Description</h3><p>We’ve seen how S-box substitution provides confusion. The other crucial property described by Shannon is “diffusion”. This relates to how every part of a cipher’s input should spread to every part of the output.</p><p>Substitution on its own creates non-linearity, however it doesn’t distribute it over the entire state. Without diffusion, the same byte in the same position would get the same transformations applied to it each round. This would allow cryptanalysts to attack each byte position in the state matrix separately. We need to alternate substitutions by scrambling the state (in an invertible way) so that substitutions applied on one byte influence all other bytes in the state. Each input into the next S-box then becomes a function of multiple bytes, meaning that with every round the algebraic complexity of the system increases enormously.</p><blockquote><p>An ideal amount of diffusion causes a change of one bit in the plaintext to lead to a change in statistically half the bits of the ciphertext. This desirable outcome is called the <a href="https://en.wikipedia.org/wiki/Avalanche_effect">Avalanche effect</a>.</p></blockquote><p>The <em>ShiftRows</em> and <em>MixColumns</em> steps combine to achieve this. They work together to ensure every byte affects every other byte in the state within just two rounds.</p><p><em>ShiftRows</em> is the most simple transformation in AES. It keeps the first row of the state matrix the same. The second row is shifted over one column to the left, wrapping around. The third row is shifted two columns, the fourth row by three. Wikipedia puts it nicely: “the importance of this step is to avoid the columns being encrypted independently, in which case AES degenerates into four independent block ciphers.”</p><p><img src="https://cryptohack.org/static/img/aes/ShiftRows.png" alt="diagram showing ShiftRows"></p><p><em>MixColumns</em> is more complex. It performs Matrix multiplication in Rijndael’s Galois field between the columns of the state matrix and a preset matrix. Each single byte of each column therefore affects all the bytes of the resulting column. The implementation details are nuanced; <a href="https://www.samiam.org/mix-column.html">this page</a> and <a href="https://en.wikipedia.org/wiki/Rijndael_MixColumns">Wikipedia</a> do a good job of covering them.</p><p><img src="https://cryptohack.org/static/img/aes/MixColumns.png" alt="diagram showing MixColumns"></p><p>We’ve provided code to perform MixColumns and the forward ShiftRows operation. After implementing <code>inv_shift_rows</code>, take the state, run <code>inv_mix_columns</code> on it, then <code>inv_shift_rows</code>, convert to bytes and you will have your flag.</p><h3 id="Analyze-5"><a href="#Analyze-5" class="headerlink" title="Analyze"></a>Analyze</h3><p>首先是补全 inv_shift_rows()，参考 shift_rows()，发现是给第 n 行向左移动 n 个单位 ，那 inv_shift_rows 就给第 n 行向右移动 n 个单位。</p><p>然后根据 description 依次运行 <code>inv_mix_columns(state)</code> <code>inv_shift_rows(state)</code>，然后把前面用过的矩阵转字节的函数 matrix2bytes() 搬过来，输出一下。</p><h3 id="Code-3"><a href="#Code-3" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">inv_shift_rows</span>(<span class="params">s</span>):</span><br><span class="line">    s[<span class="number">0</span>][<span class="number">1</span>], s[<span class="number">1</span>][<span class="number">1</span>], s[<span class="number">2</span>][<span class="number">1</span>], s[<span class="number">3</span>][<span class="number">1</span>] = s[<span class="number">3</span>][<span class="number">1</span>], s[<span class="number">0</span>][<span class="number">1</span>], s[<span class="number">1</span>][<span class="number">1</span>], s[<span class="number">2</span>][<span class="number">1</span>]</span><br><span class="line">    s[<span class="number">0</span>][<span class="number">2</span>], s[<span class="number">1</span>][<span class="number">2</span>], s[<span class="number">2</span>][<span class="number">2</span>], s[<span class="number">3</span>][<span class="number">2</span>] = s[<span class="number">2</span>][<span class="number">2</span>], s[<span class="number">3</span>][<span class="number">2</span>], s[<span class="number">0</span>][<span class="number">2</span>], s[<span class="number">1</span>][<span class="number">2</span>]</span><br><span class="line">    s[<span class="number">0</span>][<span class="number">3</span>], s[<span class="number">1</span>][<span class="number">3</span>], s[<span class="number">2</span>][<span class="number">3</span>], s[<span class="number">3</span>][<span class="number">3</span>] = s[<span class="number">1</span>][<span class="number">3</span>], s[<span class="number">2</span>][<span class="number">3</span>], s[<span class="number">3</span>][<span class="number">3</span>], s[<span class="number">0</span>][<span class="number">3</span>]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">matrix2bytes</span>(<span class="params">matrix</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot; Converts a 4x4 matrix into a 16-byte array.  &quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">bytes</span>(<span class="built_in">sum</span>(matrix, []))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">inv_mix_columns(state)</span><br><span class="line">inv_shift_rows(state)</span><br><span class="line"><span class="built_in">print</span>(matrix2bytes(state))</span><br></pre></td></tr></table></figure><h2 id="Bringing-It-All-Together"><a href="#Bringing-It-All-Together" class="headerlink" title="Bringing It All Together"></a>Bringing It All Together</h2><h3 id="Description-6"><a href="#Description-6" class="headerlink" title="Description"></a>Description</h3><p>Apart from the <strong>KeyExpansion</strong> phase, we’ve sketched out all the components of AES. We’ve shown how <em>SubBytes</em> provides confusion and <em>ShiftRows</em> and <em>MixColumns</em> provide diffusion, and how these two properties work together to repeatedly circulate non-linear transformations over the state. Finally, <em>AddRoundKey</em> seeds the key into this substitution-permutation network, making the cipher a keyed permutation.</p><p>Decryption involves performing the steps described in the “Structure of AES” challenge in reverse, applying the inverse operations. Note that the KeyExpansion still needs to be run first, and the round keys will be used in reverse order. <em>AddRoundKey</em> and its inverse are identical as XOR has the self-inverse property.</p><p><img src="https://cryptohack.org/static/img/aes/Structure2.png" alt="diagram showing AES decryption"></p><p>We’ve provided the key expansion code, and ciphertext that’s been properly encrypted by AES-128. Copy in all the building blocks you’ve coded so far, and complete the <code>decrypt</code> function that implements the steps shown in the diagram. The decrypted plaintext is the flag.</p><p>Yes, you can cheat on this challenge, but where’s the fun in that?</p><p>The code used in these exercises has been taken from Bo Zhu’s super simple Python AES implementation, so we’ve reproduced the license here.</p><h3 id="Analyze-6"><a href="#Analyze-6" class="headerlink" title="Analyze"></a>Analyze</h3><p>这题最头疼了，开始没明白到底要啥，看了半天发现是要补全好几处代码，而且给的 .py 文件还各种报错，很烦就是。</p><p>后面发现这是 AES 基础的最后一道相当于总结的题，就直接把前面几道题用到的函数和矩阵啥的全粘过来了，然后看了看有注释但没代码的地方，几乎是把前几个文件的代码拼到一起咯。然后基本就是一个完整的 AES。</p><p>还有，前面有一道题提到用了 pwn 库的 xor() 函数，现在想给自己埋咯。</p><p>最后代码一直报错，看了看日志，手写了一下 xor，居然就很顺利了？</p><p>把 pwn 库埋咯！（再次</p><p>（因为这题需要自己写的代码分布比较零散，找起来也比较麻烦，所以干脆把全部代码贴上来。）</p><h3 id="Code-4"><a href="#Code-4" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">N_ROUNDS = <span class="number">10</span></span><br><span class="line"></span><br><span class="line">key = <span class="string">b&#x27;\xc3,\\\xa6\xb5\x80^\x0c\xdb\x8d\xa5z*\xb6\xfe\\&#x27;</span></span><br><span class="line">ciphertext = <span class="string">b&#x27;\xd1O\x14j\xa4+O\xb6\xa1\xc4\x08B)\x8f\x12\xdd&#x27;</span></span><br><span class="line">s_box = (</span><br><span class="line">    <span class="number">0x63</span>, <span class="number">0x7C</span>, <span class="number">0x77</span>, <span class="number">0x7B</span>, <span class="number">0xF2</span>, <span class="number">0x6B</span>, <span class="number">0x6F</span>, <span class="number">0xC5</span>, <span class="number">0x30</span>, <span class="number">0x01</span>, <span class="number">0x67</span>, <span class="number">0x2B</span>, <span class="number">0xFE</span>, <span class="number">0xD7</span>, <span class="number">0xAB</span>, <span class="number">0x76</span>,</span><br><span class="line">    <span class="number">0xCA</span>, <span class="number">0x82</span>, <span class="number">0xC9</span>, <span class="number">0x7D</span>, <span class="number">0xFA</span>, <span class="number">0x59</span>, <span class="number">0x47</span>, <span class="number">0xF0</span>, <span class="number">0xAD</span>, <span class="number">0xD4</span>, <span class="number">0xA2</span>, <span class="number">0xAF</span>, <span class="number">0x9C</span>, <span class="number">0xA4</span>, <span class="number">0x72</span>, <span class="number">0xC0</span>,</span><br><span class="line">    <span class="number">0xB7</span>, <span class="number">0xFD</span>, <span class="number">0x93</span>, <span class="number">0x26</span>, <span class="number">0x36</span>, <span class="number">0x3F</span>, <span class="number">0xF7</span>, <span class="number">0xCC</span>, <span class="number">0x34</span>, <span class="number">0xA5</span>, <span class="number">0xE5</span>, <span class="number">0xF1</span>, <span class="number">0x71</span>, <span class="number">0xD8</span>, <span class="number">0x31</span>, <span class="number">0x15</span>,</span><br><span class="line">    <span class="number">0x04</span>, <span class="number">0xC7</span>, <span class="number">0x23</span>, <span class="number">0xC3</span>, <span class="number">0x18</span>, <span class="number">0x96</span>, <span class="number">0x05</span>, <span class="number">0x9A</span>, <span class="number">0x07</span>, <span class="number">0x12</span>, <span class="number">0x80</span>, <span class="number">0xE2</span>, <span class="number">0xEB</span>, <span class="number">0x27</span>, <span class="number">0xB2</span>, <span class="number">0x75</span>,</span><br><span class="line">    <span class="number">0x09</span>, <span class="number">0x83</span>, <span class="number">0x2C</span>, <span class="number">0x1A</span>, <span class="number">0x1B</span>, <span class="number">0x6E</span>, <span class="number">0x5A</span>, <span class="number">0xA0</span>, <span class="number">0x52</span>, <span class="number">0x3B</span>, <span class="number">0xD6</span>, <span class="number">0xB3</span>, <span class="number">0x29</span>, <span class="number">0xE3</span>, <span class="number">0x2F</span>, <span class="number">0x84</span>,</span><br><span class="line">    <span class="number">0x53</span>, <span class="number">0xD1</span>, <span class="number">0x00</span>, <span class="number">0xED</span>, <span class="number">0x20</span>, <span class="number">0xFC</span>, <span class="number">0xB1</span>, <span class="number">0x5B</span>, <span class="number">0x6A</span>, <span class="number">0xCB</span>, <span class="number">0xBE</span>, <span class="number">0x39</span>, <span class="number">0x4A</span>, <span class="number">0x4C</span>, <span class="number">0x58</span>, <span class="number">0xCF</span>,</span><br><span class="line">    <span class="number">0xD0</span>, <span class="number">0xEF</span>, <span class="number">0xAA</span>, <span class="number">0xFB</span>, <span class="number">0x43</span>, <span class="number">0x4D</span>, <span class="number">0x33</span>, <span class="number">0x85</span>, <span class="number">0x45</span>, <span class="number">0xF9</span>, <span class="number">0x02</span>, <span class="number">0x7F</span>, <span class="number">0x50</span>, <span class="number">0x3C</span>, <span class="number">0x9F</span>, <span class="number">0xA8</span>,</span><br><span class="line">    <span class="number">0x51</span>, <span class="number">0xA3</span>, <span class="number">0x40</span>, <span class="number">0x8F</span>, <span class="number">0x92</span>, <span class="number">0x9D</span>, <span class="number">0x38</span>, <span class="number">0xF5</span>, <span class="number">0xBC</span>, <span class="number">0xB6</span>, <span class="number">0xDA</span>, <span class="number">0x21</span>, <span class="number">0x10</span>, <span class="number">0xFF</span>, <span class="number">0xF3</span>, <span class="number">0xD2</span>,</span><br><span class="line">    <span class="number">0xCD</span>, <span class="number">0x0C</span>, <span class="number">0x13</span>, <span class="number">0xEC</span>, <span class="number">0x5F</span>, <span class="number">0x97</span>, <span class="number">0x44</span>, <span class="number">0x17</span>, <span class="number">0xC4</span>, <span class="number">0xA7</span>, <span class="number">0x7E</span>, <span class="number">0x3D</span>, <span class="number">0x64</span>, <span class="number">0x5D</span>, <span class="number">0x19</span>, <span class="number">0x73</span>,</span><br><span class="line">    <span class="number">0x60</span>, <span class="number">0x81</span>, <span class="number">0x4F</span>, <span class="number">0xDC</span>, <span class="number">0x22</span>, <span class="number">0x2A</span>, <span class="number">0x90</span>, <span class="number">0x88</span>, <span class="number">0x46</span>, <span class="number">0xEE</span>, <span class="number">0xB8</span>, <span class="number">0x14</span>, <span class="number">0xDE</span>, <span class="number">0x5E</span>, <span class="number">0x0B</span>, <span class="number">0xDB</span>,</span><br><span class="line">    <span class="number">0xE0</span>, <span class="number">0x32</span>, <span class="number">0x3A</span>, <span class="number">0x0A</span>, <span class="number">0x49</span>, <span class="number">0x06</span>, <span class="number">0x24</span>, <span class="number">0x5C</span>, <span class="number">0xC2</span>, <span class="number">0xD3</span>, <span class="number">0xAC</span>, <span class="number">0x62</span>, <span class="number">0x91</span>, <span class="number">0x95</span>, <span class="number">0xE4</span>, <span class="number">0x79</span>,</span><br><span class="line">    <span class="number">0xE7</span>, <span class="number">0xC8</span>, <span class="number">0x37</span>, <span class="number">0x6D</span>, <span class="number">0x8D</span>, <span class="number">0xD5</span>, <span class="number">0x4E</span>, <span class="number">0xA9</span>, <span class="number">0x6C</span>, <span class="number">0x56</span>, <span class="number">0xF4</span>, <span class="number">0xEA</span>, <span class="number">0x65</span>, <span class="number">0x7A</span>, <span class="number">0xAE</span>, <span class="number">0x08</span>,</span><br><span class="line">    <span class="number">0xBA</span>, <span class="number">0x78</span>, <span class="number">0x25</span>, <span class="number">0x2E</span>, <span class="number">0x1C</span>, <span class="number">0xA6</span>, <span class="number">0xB4</span>, <span class="number">0xC6</span>, <span class="number">0xE8</span>, <span class="number">0xDD</span>, <span class="number">0x74</span>, <span class="number">0x1F</span>, <span class="number">0x4B</span>, <span class="number">0xBD</span>, <span class="number">0x8B</span>, <span class="number">0x8A</span>,</span><br><span class="line">    <span class="number">0x70</span>, <span class="number">0x3E</span>, <span class="number">0xB5</span>, <span class="number">0x66</span>, <span class="number">0x48</span>, <span class="number">0x03</span>, <span class="number">0xF6</span>, <span class="number">0x0E</span>, <span class="number">0x61</span>, <span class="number">0x35</span>, <span class="number">0x57</span>, <span class="number">0xB9</span>, <span class="number">0x86</span>, <span class="number">0xC1</span>, <span class="number">0x1D</span>, <span class="number">0x9E</span>,</span><br><span class="line">    <span class="number">0xE1</span>, <span class="number">0xF8</span>, <span class="number">0x98</span>, <span class="number">0x11</span>, <span class="number">0x69</span>, <span class="number">0xD9</span>, <span class="number">0x8E</span>, <span class="number">0x94</span>, <span class="number">0x9B</span>, <span class="number">0x1E</span>, <span class="number">0x87</span>, <span class="number">0xE9</span>, <span class="number">0xCE</span>, <span class="number">0x55</span>, <span class="number">0x28</span>, <span class="number">0xDF</span>,</span><br><span class="line">    <span class="number">0x8C</span>, <span class="number">0xA1</span>, <span class="number">0x89</span>, <span class="number">0x0D</span>, <span class="number">0xBF</span>, <span class="number">0xE6</span>, <span class="number">0x42</span>, <span class="number">0x68</span>, <span class="number">0x41</span>, <span class="number">0x99</span>, <span class="number">0x2D</span>, <span class="number">0x0F</span>, <span class="number">0xB0</span>, <span class="number">0x54</span>, <span class="number">0xBB</span>, <span class="number">0x16</span>,</span><br><span class="line">)</span><br><span class="line">inv_s_box = (</span><br><span class="line">    <span class="number">0x52</span>, <span class="number">0x09</span>, <span class="number">0x6A</span>, <span class="number">0xD5</span>, <span class="number">0x30</span>, <span class="number">0x36</span>, <span class="number">0xA5</span>, <span class="number">0x38</span>, <span class="number">0xBF</span>, <span class="number">0x40</span>, <span class="number">0xA3</span>, <span class="number">0x9E</span>, <span class="number">0x81</span>, <span class="number">0xF3</span>, <span class="number">0xD7</span>, <span class="number">0xFB</span>,</span><br><span class="line">    <span class="number">0x7C</span>, <span class="number">0xE3</span>, <span class="number">0x39</span>, <span class="number">0x82</span>, <span class="number">0x9B</span>, <span class="number">0x2F</span>, <span class="number">0xFF</span>, <span class="number">0x87</span>, <span class="number">0x34</span>, <span class="number">0x8E</span>, <span class="number">0x43</span>, <span class="number">0x44</span>, <span class="number">0xC4</span>, <span class="number">0xDE</span>, <span class="number">0xE9</span>, <span class="number">0xCB</span>,</span><br><span class="line">    <span class="number">0x54</span>, <span class="number">0x7B</span>, <span class="number">0x94</span>, <span class="number">0x32</span>, <span class="number">0xA6</span>, <span class="number">0xC2</span>, <span class="number">0x23</span>, <span class="number">0x3D</span>, <span class="number">0xEE</span>, <span class="number">0x4C</span>, <span class="number">0x95</span>, <span class="number">0x0B</span>, <span class="number">0x42</span>, <span class="number">0xFA</span>, <span class="number">0xC3</span>, <span class="number">0x4E</span>,</span><br><span class="line">    <span class="number">0x08</span>, <span class="number">0x2E</span>, <span class="number">0xA1</span>, <span class="number">0x66</span>, <span class="number">0x28</span>, <span class="number">0xD9</span>, <span class="number">0x24</span>, <span class="number">0xB2</span>, <span class="number">0x76</span>, <span class="number">0x5B</span>, <span class="number">0xA2</span>, <span class="number">0x49</span>, <span class="number">0x6D</span>, <span class="number">0x8B</span>, <span class="number">0xD1</span>, <span class="number">0x25</span>,</span><br><span class="line">    <span class="number">0x72</span>, <span class="number">0xF8</span>, <span class="number">0xF6</span>, <span class="number">0x64</span>, <span class="number">0x86</span>, <span class="number">0x68</span>, <span class="number">0x98</span>, <span class="number">0x16</span>, <span class="number">0xD4</span>, <span class="number">0xA4</span>, <span class="number">0x5C</span>, <span class="number">0xCC</span>, <span class="number">0x5D</span>, <span class="number">0x65</span>, <span class="number">0xB6</span>, <span class="number">0x92</span>,</span><br><span class="line">    <span class="number">0x6C</span>, <span class="number">0x70</span>, <span class="number">0x48</span>, <span class="number">0x50</span>, <span class="number">0xFD</span>, <span class="number">0xED</span>, <span class="number">0xB9</span>, <span class="number">0xDA</span>, <span class="number">0x5E</span>, <span class="number">0x15</span>, <span class="number">0x46</span>, <span class="number">0x57</span>, <span class="number">0xA7</span>, <span class="number">0x8D</span>, <span class="number">0x9D</span>, <span class="number">0x84</span>,</span><br><span class="line">    <span class="number">0x90</span>, <span class="number">0xD8</span>, <span class="number">0xAB</span>, <span class="number">0x00</span>, <span class="number">0x8C</span>, <span class="number">0xBC</span>, <span class="number">0xD3</span>, <span class="number">0x0A</span>, <span class="number">0xF7</span>, <span class="number">0xE4</span>, <span class="number">0x58</span>, <span class="number">0x05</span>, <span class="number">0xB8</span>, <span class="number">0xB3</span>, <span class="number">0x45</span>, <span class="number">0x06</span>,</span><br><span class="line">    <span class="number">0xD0</span>, <span class="number">0x2C</span>, <span class="number">0x1E</span>, <span class="number">0x8F</span>, <span class="number">0xCA</span>, <span class="number">0x3F</span>, <span class="number">0x0F</span>, <span class="number">0x02</span>, <span class="number">0xC1</span>, <span class="number">0xAF</span>, <span class="number">0xBD</span>, <span class="number">0x03</span>, <span class="number">0x01</span>, <span class="number">0x13</span>, <span class="number">0x8A</span>, <span class="number">0x6B</span>,</span><br><span class="line">    <span class="number">0x3A</span>, <span class="number">0x91</span>, <span class="number">0x11</span>, <span class="number">0x41</span>, <span class="number">0x4F</span>, <span class="number">0x67</span>, <span class="number">0xDC</span>, <span class="number">0xEA</span>, <span class="number">0x97</span>, <span class="number">0xF2</span>, <span class="number">0xCF</span>, <span class="number">0xCE</span>, <span class="number">0xF0</span>, <span class="number">0xB4</span>, <span class="number">0xE6</span>, <span class="number">0x73</span>,</span><br><span class="line">    <span class="number">0x96</span>, <span class="number">0xAC</span>, <span class="number">0x74</span>, <span class="number">0x22</span>, <span class="number">0xE7</span>, <span class="number">0xAD</span>, <span class="number">0x35</span>, <span class="number">0x85</span>, <span class="number">0xE2</span>, <span class="number">0xF9</span>, <span class="number">0x37</span>, <span class="number">0xE8</span>, <span class="number">0x1C</span>, <span class="number">0x75</span>, <span class="number">0xDF</span>, <span class="number">0x6E</span>,</span><br><span class="line">    <span class="number">0x47</span>, <span class="number">0xF1</span>, <span class="number">0x1A</span>, <span class="number">0x71</span>, <span class="number">0x1D</span>, <span class="number">0x29</span>, <span class="number">0xC5</span>, <span class="number">0x89</span>, <span class="number">0x6F</span>, <span class="number">0xB7</span>, <span class="number">0x62</span>, <span class="number">0x0E</span>, <span class="number">0xAA</span>, <span class="number">0x18</span>, <span class="number">0xBE</span>, <span class="number">0x1B</span>,</span><br><span class="line">    <span class="number">0xFC</span>, <span class="number">0x56</span>, <span class="number">0x3E</span>, <span class="number">0x4B</span>, <span class="number">0xC6</span>, <span class="number">0xD2</span>, <span class="number">0x79</span>, <span class="number">0x20</span>, <span class="number">0x9A</span>, <span class="number">0xDB</span>, <span class="number">0xC0</span>, <span class="number">0xFE</span>, <span class="number">0x78</span>, <span class="number">0xCD</span>, <span class="number">0x5A</span>, <span class="number">0xF4</span>,</span><br><span class="line">    <span class="number">0x1F</span>, <span class="number">0xDD</span>, <span class="number">0xA8</span>, <span class="number">0x33</span>, <span class="number">0x88</span>, <span class="number">0x07</span>, <span class="number">0xC7</span>, <span class="number">0x31</span>, <span class="number">0xB1</span>, <span class="number">0x12</span>, <span class="number">0x10</span>, <span class="number">0x59</span>, <span class="number">0x27</span>, <span class="number">0x80</span>, <span class="number">0xEC</span>, <span class="number">0x5F</span>,</span><br><span class="line">    <span class="number">0x60</span>, <span class="number">0x51</span>, <span class="number">0x7F</span>, <span class="number">0xA9</span>, <span class="number">0x19</span>, <span class="number">0xB5</span>, <span class="number">0x4A</span>, <span class="number">0x0D</span>, <span class="number">0x2D</span>, <span class="number">0xE5</span>, <span class="number">0x7A</span>, <span class="number">0x9F</span>, <span class="number">0x93</span>, <span class="number">0xC9</span>, <span class="number">0x9C</span>, <span class="number">0xEF</span>,</span><br><span class="line">    <span class="number">0xA0</span>, <span class="number">0xE0</span>, <span class="number">0x3B</span>, <span class="number">0x4D</span>, <span class="number">0xAE</span>, <span class="number">0x2A</span>, <span class="number">0xF5</span>, <span class="number">0xB0</span>, <span class="number">0xC8</span>, <span class="number">0xEB</span>, <span class="number">0xBB</span>, <span class="number">0x3C</span>, <span class="number">0x83</span>, <span class="number">0x53</span>, <span class="number">0x99</span>, <span class="number">0x61</span>,</span><br><span class="line">    <span class="number">0x17</span>, <span class="number">0x2B</span>, <span class="number">0x04</span>, <span class="number">0x7E</span>, <span class="number">0xBA</span>, <span class="number">0x77</span>, <span class="number">0xD6</span>, <span class="number">0x26</span>, <span class="number">0xE1</span>, <span class="number">0x69</span>, <span class="number">0x14</span>, <span class="number">0x63</span>, <span class="number">0x55</span>, <span class="number">0x21</span>, <span class="number">0x0C</span>, <span class="number">0x7D</span>,</span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">bytes2matrix</span>(<span class="params">text</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot; Converts a 16-byte array into a 4x4 matrix.  &quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">return</span> [<span class="built_in">list</span>(text[i:i+<span class="number">4</span>]) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="built_in">len</span>(text), <span class="number">4</span>)]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">matrix2bytes</span>(<span class="params">matrix</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot; Converts a 4x4 matrix into a 16-byte array.  &quot;&quot;&quot;</span></span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">bytes</span>(<span class="built_in">sum</span>(matrix, []))</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">add_round_key</span>(<span class="params">s, k</span>):</span><br><span class="line">    <span class="keyword">return</span> [</span><br><span class="line">        [s[i][j] ^ k[i][j] <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>)]</span><br><span class="line">        <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>)</span><br><span class="line">    ]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">sub_bytes</span>(<span class="params">s, sbox=s_box</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">        <span class="keyword">for</span> j <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">            s[i][j] = sbox[s[i][j]]</span><br><span class="line">    <span class="keyword">return</span> s</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">shift_rows</span>(<span class="params">s</span>):</span><br><span class="line">    s[<span class="number">0</span>][<span class="number">1</span>], s[<span class="number">1</span>][<span class="number">1</span>], s[<span class="number">2</span>][<span class="number">1</span>], s[<span class="number">3</span>][<span class="number">1</span>] = s[<span class="number">1</span>][<span class="number">1</span>], s[<span class="number">2</span>][<span class="number">1</span>], s[<span class="number">3</span>][<span class="number">1</span>], s[<span class="number">0</span>][<span class="number">1</span>]</span><br><span class="line">    s[<span class="number">0</span>][<span class="number">2</span>], s[<span class="number">1</span>][<span class="number">2</span>], s[<span class="number">2</span>][<span class="number">2</span>], s[<span class="number">3</span>][<span class="number">2</span>] = s[<span class="number">2</span>][<span class="number">2</span>], s[<span class="number">3</span>][<span class="number">2</span>], s[<span class="number">0</span>][<span class="number">2</span>], s[<span class="number">1</span>][<span class="number">2</span>]</span><br><span class="line">    s[<span class="number">0</span>][<span class="number">3</span>], s[<span class="number">1</span>][<span class="number">3</span>], s[<span class="number">2</span>][<span class="number">3</span>], s[<span class="number">3</span>][<span class="number">3</span>] = s[<span class="number">3</span>][<span class="number">3</span>], s[<span class="number">0</span>][<span class="number">3</span>], s[<span class="number">1</span>][<span class="number">3</span>], s[<span class="number">2</span>][<span class="number">3</span>]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">inv_shift_rows</span>(<span class="params">s</span>):</span><br><span class="line">    s[<span class="number">0</span>][<span class="number">1</span>], s[<span class="number">1</span>][<span class="number">1</span>], s[<span class="number">2</span>][<span class="number">1</span>], s[<span class="number">3</span>][<span class="number">1</span>] = s[<span class="number">3</span>][<span class="number">1</span>], s[<span class="number">0</span>][<span class="number">1</span>], s[<span class="number">1</span>][<span class="number">1</span>], s[<span class="number">2</span>][<span class="number">1</span>]</span><br><span class="line">    s[<span class="number">0</span>][<span class="number">2</span>], s[<span class="number">1</span>][<span class="number">2</span>], s[<span class="number">2</span>][<span class="number">2</span>], s[<span class="number">3</span>][<span class="number">2</span>] = s[<span class="number">2</span>][<span class="number">2</span>], s[<span class="number">3</span>][<span class="number">2</span>], s[<span class="number">0</span>][<span class="number">2</span>], s[<span class="number">1</span>][<span class="number">2</span>]</span><br><span class="line">    s[<span class="number">0</span>][<span class="number">3</span>], s[<span class="number">1</span>][<span class="number">3</span>], s[<span class="number">2</span>][<span class="number">3</span>], s[<span class="number">3</span>][<span class="number">3</span>] = s[<span class="number">1</span>][<span class="number">3</span>], s[<span class="number">2</span>][<span class="number">3</span>], s[<span class="number">3</span>][<span class="number">3</span>], s[<span class="number">0</span>][<span class="number">3</span>]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment"># learned from http://cs.ucsb.edu/~koc/cs178/projects/JT/aes.c</span></span><br><span class="line">xtime = <span class="keyword">lambda</span> a: (((a &lt;&lt; <span class="number">1</span>) ^ <span class="number">0x1B</span>) &amp; <span class="number">0xFF</span>) <span class="keyword">if</span> (a &amp; <span class="number">0x80</span>) <span class="keyword">else</span> (a &lt;&lt; <span class="number">1</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mix_single_column</span>(<span class="params">a</span>):</span><br><span class="line">    <span class="comment"># see Sec 4.1.2 in The Design of Rijndael</span></span><br><span class="line">    t = a[<span class="number">0</span>] ^ a[<span class="number">1</span>] ^ a[<span class="number">2</span>] ^ a[<span class="number">3</span>]</span><br><span class="line">    u = a[<span class="number">0</span>]</span><br><span class="line">    a[<span class="number">0</span>] ^= t ^ xtime(a[<span class="number">0</span>] ^ a[<span class="number">1</span>])</span><br><span class="line">    a[<span class="number">1</span>] ^= t ^ xtime(a[<span class="number">1</span>] ^ a[<span class="number">2</span>])</span><br><span class="line">    a[<span class="number">2</span>] ^= t ^ xtime(a[<span class="number">2</span>] ^ a[<span class="number">3</span>])</span><br><span class="line">    a[<span class="number">3</span>] ^= t ^ xtime(a[<span class="number">3</span>] ^ u)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mix_columns</span>(<span class="params">s</span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">        mix_single_column(s[i])</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">inv_mix_columns</span>(<span class="params">s</span>):</span><br><span class="line">    <span class="comment"># see Sec 4.1.3 in The Design of Rijndael</span></span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">4</span>):</span><br><span class="line">        u = xtime(xtime(s[i][<span class="number">0</span>] ^ s[i][<span class="number">2</span>]))</span><br><span class="line">        v = xtime(xtime(s[i][<span class="number">1</span>] ^ s[i][<span class="number">3</span>]))</span><br><span class="line">        s[i][<span class="number">0</span>] ^= u</span><br><span class="line">        s[i][<span class="number">1</span>] ^= v</span><br><span class="line">        s[i][<span class="number">2</span>] ^= u</span><br><span class="line">        s[i][<span class="number">3</span>] ^= v</span><br><span class="line"></span><br><span class="line">    mix_columns(s)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">expand_key</span>(<span class="params">master_key</span>):</span><br><span class="line">    <span class="string">&quot;&quot;&quot;</span></span><br><span class="line"><span class="string">    Expands and returns a list of key matrices for the given master_key.</span></span><br><span class="line"><span class="string">    &quot;&quot;&quot;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># Round constants https://en.wikipedia.org/wiki/AES_key_schedule#Round_constants</span></span><br><span class="line">    r_con = (</span><br><span class="line">        <span class="number">0x00</span>, <span class="number">0x01</span>, <span class="number">0x02</span>, <span class="number">0x04</span>, <span class="number">0x08</span>, <span class="number">0x10</span>, <span class="number">0x20</span>, <span class="number">0x40</span>,</span><br><span class="line">        <span class="number">0x80</span>, <span class="number">0x1B</span>, <span class="number">0x36</span>, <span class="number">0x6C</span>, <span class="number">0xD8</span>, <span class="number">0xAB</span>, <span class="number">0x4D</span>, <span class="number">0x9A</span>,</span><br><span class="line">        <span class="number">0x2F</span>, <span class="number">0x5E</span>, <span class="number">0xBC</span>, <span class="number">0x63</span>, <span class="number">0xC6</span>, <span class="number">0x97</span>, <span class="number">0x35</span>, <span class="number">0x6A</span>,</span><br><span class="line">        <span class="number">0xD4</span>, <span class="number">0xB3</span>, <span class="number">0x7D</span>, <span class="number">0xFA</span>, <span class="number">0xEF</span>, <span class="number">0xC5</span>, <span class="number">0x91</span>, <span class="number">0x39</span>,</span><br><span class="line">    )</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Initialize round keys with raw key material.</span></span><br><span class="line">    key_columns = bytes2matrix(master_key)</span><br><span class="line">    iteration_size = <span class="built_in">len</span>(master_key) // <span class="number">4</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># Each iteration has exactly as many columns as the key material.</span></span><br><span class="line">    i = <span class="number">1</span></span><br><span class="line">    <span class="keyword">while</span> <span class="built_in">len</span>(key_columns) &lt; (N_ROUNDS + <span class="number">1</span>) * <span class="number">4</span>:</span><br><span class="line">        <span class="comment"># Copy previous word.</span></span><br><span class="line">        word = <span class="built_in">list</span>(key_columns[-<span class="number">1</span>])</span><br><span class="line"></span><br><span class="line">        <span class="comment"># Perform schedule_core once every &quot;row&quot;.</span></span><br><span class="line">        <span class="keyword">if</span> <span class="built_in">len</span>(key_columns) % iteration_size == <span class="number">0</span>:</span><br><span class="line">            <span class="comment"># Circular shift.</span></span><br><span class="line">            word.append(word.pop(<span class="number">0</span>))</span><br><span class="line">            <span class="comment"># Map to S-BOX.</span></span><br><span class="line">            word = [s_box[b] <span class="keyword">for</span> b <span class="keyword">in</span> word]</span><br><span class="line">            <span class="comment"># XOR with first byte of R-CON, since the others bytes of R-CON are 0.</span></span><br><span class="line">            word[<span class="number">0</span>] ^= r_con[i]</span><br><span class="line">            i += <span class="number">1</span></span><br><span class="line">        <span class="keyword">elif</span> <span class="built_in">len</span>(master_key) == <span class="number">32</span> <span class="keyword">and</span> <span class="built_in">len</span>(key_columns) % iteration_size == <span class="number">4</span>:</span><br><span class="line">            <span class="comment"># Run word through S-box in the fourth iteration when using a</span></span><br><span class="line">            <span class="comment"># 256-bit key.</span></span><br><span class="line">            word = [s_box[b] <span class="keyword">for</span> b <span class="keyword">in</span> word]</span><br><span class="line"></span><br><span class="line">        <span class="comment"># XOR with equivalent word from previous iteration.</span></span><br><span class="line">        word = <span class="built_in">bytes</span>(i ^ j <span class="keyword">for</span> i, j <span class="keyword">in</span> <span class="built_in">zip</span>(word, key_columns[-iteration_size]))</span><br><span class="line">        key_columns.append(word)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Group key words in 4x4 byte matrices.</span></span><br><span class="line">    <span class="keyword">return</span> [key_columns[<span class="number">4</span> * i: <span class="number">4</span>*(i+<span class="number">1</span>)] <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="built_in">len</span>(key_columns) // <span class="number">4</span>)]</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">decrypt</span>(<span class="params">key, ciphertext</span>):</span><br><span class="line">    round_keys = expand_key(key)  <span class="comment"># Remember to start from the last round key and work backwards through them when decrypting</span></span><br><span class="line"></span><br><span class="line">    <span class="comment"># Convert ciphertext to state matrix</span></span><br><span class="line">    state = bytes2matrix(ciphertext)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Initial add round key step</span></span><br><span class="line">    state = add_round_key(state, round_keys[-<span class="number">1</span>])</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(N_ROUNDS - <span class="number">1</span>, <span class="number">0</span>, -<span class="number">1</span>):</span><br><span class="line">        inv_shift_rows(state)</span><br><span class="line">        state = sub_bytes(state, inv_s_box)</span><br><span class="line">        state = add_round_key(state, round_keys[i])</span><br><span class="line">        inv_mix_columns(state)</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Run final round (skips the InvMixColumns step)</span></span><br><span class="line">    inv_shift_rows(state)</span><br><span class="line">    state = sub_bytes(state, inv_s_box)</span><br><span class="line">    state = add_round_key(state, round_keys[<span class="number">0</span>])</span><br><span class="line"></span><br><span class="line">    <span class="comment"># Convert state matrix to plaintext</span></span><br><span class="line">    <span class="keyword">return</span> matrix2bytes(state)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(decrypt(key, ciphertext))</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;第三章好像是做的最迷的&lt;/p&gt;
    
    </summary>
    
      <category term="学习" scheme="http://smilin9.com/categories/%E5%AD%A6%E4%B9%A0/"/>
    
    
      <category term="cryptohack" scheme="http://smilin9.com/tags/cryptohack/"/>
    
  </entry>
  
  <entry>
    <title>Modular Arithmetic</title>
    <link href="http://smilin9.com/2022/05/03/Modular%20Arithmetic/"/>
    <id>http://smilin9.com/2022/05/03/Modular Arithmetic/</id>
    <published>2022-05-03T11:56:00.000Z</published>
    <updated>2022-12-12T14:57:53.173Z</updated>
    
    <content type="html"><![CDATA[<p>第二章也做完咯~</p><span id="more"></span><p>看到这章的标题就感觉要寄。</p><p>进去一看果然，全是数学。。（数学废物笑不出来</p><p>做了近两天，我只能说数学博大精深，做数学题真的会谢。。</p><p>交完最后一题的 flag 觉得整个人都放松下来了，然后就感觉精疲力尽。</p><p>做的很艰难，尤其 python 用的还是那么不利索。</p><p>由于有些题的代码是通过推导之后直接通过数学定理化简，所以代码很简单。</p><h2 id="Greatest-Common-Divisor"><a href="#Greatest-Common-Divisor" class="headerlink" title="Greatest Common Divisor"></a>Greatest Common Divisor</h2><h3 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h3><p>The Greatest Common Divisor (GCD), sometimes known as the highest common factor, is the largest number which divides two positive integers (a,b).</p><p>For <code>a = 12, b = 8</code> we can calculate the divisors of a: <code>&#123;1,2,3,4,6,12&#125;</code> and the divisors of b: <code>&#123;1,2,4,8&#125;</code>. Comparing these two, we see that <code>gcd(a,b) = 4</code>.</p><p>Now imagine we take <code>a = 11, b = 17</code>. Both <code>a</code> and <code>b</code> are prime numbers. As a prime number has only itself and <code>1</code> as divisors, <code>gcd(a,b) = 1</code>.</p><p>We say that for any two integers <code>a,b</code>, if <code>gcd(a,b) = 1</code> then <code>a</code> and <code>b</code> are coprime integers.</p><p>If <code>a</code> and <code>b</code> are prime, they are also coprime. If <code>a</code> is prime and <code>b &lt; a</code> then <code>a</code> and <code>b</code> are coprime.</p><blockquote><p>Think about the case for <code>a</code> prime and <code>b &gt; a</code>, why are these not necessarily coprime?</p></blockquote><p>There are many tools to calculate the GCD of two integers, but for this task we recommend looking up <a href="https://en.wikipedia.org/wiki/Euclidean_algorithm">Euclid’s Algorithm</a>.</p><p>Try coding it up; it’s only a couple of lines. Use <code>a = 12, b = 8</code> to test it.</p><p>Now calculate <code>gcd(a,b)</code> for <code>a = 66528, b = 52920</code> and enter it below.</p><h3 id="Analyze"><a href="#Analyze" class="headerlink" title="Analyze"></a>Analyze</h3><p>就是算最大公约数啦，简单写个函数就好咯。</p><p>现在再看这题是真简单啊。</p><h3 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">gcd</span>(<span class="params">a: <span class="built_in">int</span>, b: <span class="built_in">int</span></span>) -&gt; <span class="built_in">int</span>:</span><br><span class="line">    <span class="keyword">while</span> b:</span><br><span class="line">        a, b = b, a % b</span><br><span class="line">    <span class="keyword">return</span> a</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">a = <span class="built_in">int</span>(<span class="built_in">input</span>())</span><br><span class="line">b = <span class="built_in">int</span>(<span class="built_in">input</span>())</span><br><span class="line"><span class="built_in">print</span>(gcd(a, b))</span><br></pre></td></tr></table></figure><h3 id="SumUp"><a href="#SumUp" class="headerlink" title="SumUp"></a>SumUp</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 欧几里得算法，是 C 语言做过的东西</span></span><br><span class="line"><span class="comment"># function： gcd(a, b)</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">gcd</span>(<span class="params">a: <span class="built_in">int</span>, b: <span class="built_in">int</span></span>) -&gt; <span class="built_in">int</span>:</span><br><span class="line">    <span class="keyword">while</span> b:</span><br><span class="line">        a, b = b, a % b</span><br><span class="line">    <span class="keyword">return</span> a</span><br></pre></td></tr></table></figure><h2 id="Extended-GCD"><a href="#Extended-GCD" class="headerlink" title="Extended GCD"></a>Extended GCD</h2><h3 id="Description-1"><a href="#Description-1" class="headerlink" title="Description"></a>Description</h3><p>Let <code>a</code> and <code>b</code> be positive integers.</p><p>The extended Euclidean algorithm is an efficient way to find integers <code>u,v</code> such that</p><figure class="highlight livecodeserver"><table><tr><td class="code"><pre><span class="line"><span class="keyword">a</span> * u + b * v = gcd(<span class="keyword">a</span>,b)</span><br></pre></td></tr></table></figure><blockquote><p>Later, when we learn to decrypt RSA, we will need this algorithm to calculate the modular inverse of the public exponent.</p></blockquote><p>Using the two primes <code>p = 26513, q = 32321</code>, find the integers <code>u,v</code> such that</p><figure class="highlight markdown"><table><tr><td class="code"><pre><span class="line">p <span class="emphasis">* u + q *</span> v = gcd(p,q)</span><br></pre></td></tr></table></figure><p>Enter whichever of <code>u</code> and <code>v</code> is the lower number as the flag.</p><blockquote><p>Knowing that <code>p,q</code> are prime, what would you expect <code>gcd(p,q)</code> to be? For more details on the extended Euclidean algorithm, check out <a href="http://www-math.ucdenver.edu/~wcherowi/courses/m5410/exeucalg.html">this page</a>.</p></blockquote><h3 id="Analyze-1"><a href="#Analyze-1" class="headerlink" title="Analyze"></a>Analyze</h3><p>用到扩展的欧几里得算法，数学原理和辗转相除大同小异，简单代下数字手推一遍详细过程就知道怎么回事咯。</p><h3 id="Code-1"><a href="#Code-1" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">exgcd</span>(<span class="params">a: <span class="built_in">int</span>, b: <span class="built_in">int</span></span>) -&gt; (<span class="built_in">int</span>, <span class="built_in">int</span>, <span class="built_in">int</span>):</span><br><span class="line">    <span class="keyword">if</span> a &lt; b:</span><br><span class="line">        t = a</span><br><span class="line">        a = b</span><br><span class="line">        b = t</span><br><span class="line">    <span class="keyword">if</span> b == <span class="number">0</span>:</span><br><span class="line">        <span class="keyword">return</span> a, <span class="number">1</span>, <span class="number">0</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        g, x, y = exgcd(b, a % b)</span><br><span class="line">        <span class="keyword">return</span> g, y, x - (a // b) * y</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">a = <span class="built_in">int</span>(<span class="built_in">input</span>())</span><br><span class="line">b = <span class="built_in">int</span>(<span class="built_in">input</span>())</span><br><span class="line"><span class="built_in">print</span>(exgcd(a, b))</span><br></pre></td></tr></table></figure><h3 id="SumUp-1"><a href="#SumUp-1" class="headerlink" title="SumUp"></a>SumUp</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># 扩展欧几里得，不限制输入的大小顺序</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">exgcd</span>(<span class="params">a: <span class="built_in">int</span>, b: <span class="built_in">int</span></span>) -&gt; (<span class="built_in">int</span>, <span class="built_in">int</span>, <span class="built_in">int</span>):</span><br><span class="line">    <span class="keyword">if</span> a &lt; b:</span><br><span class="line">        t = a</span><br><span class="line">        a = b</span><br><span class="line">        b = t</span><br><span class="line">    <span class="keyword">if</span> b == <span class="number">0</span>:</span><br><span class="line">        <span class="keyword">return</span> a, <span class="number">1</span>, <span class="number">0</span></span><br><span class="line">    <span class="keyword">else</span>:</span><br><span class="line">        g, x, y = exgcd(b, a % b)</span><br><span class="line">        <span class="keyword">return</span> g, y, x - (a // b) * y</span><br><span class="line"><span class="comment"># ax0 + by0 = gcd(a, b)</span></span><br><span class="line"><span class="comment"># 输入 a, b</span></span><br><span class="line"><span class="comment"># 输出 g, x0, y0</span></span><br><span class="line"><span class="comment"># 其中 g = gcd(a, b)</span></span><br></pre></td></tr></table></figure><h2 id="Modular-Arithmetic-1"><a href="#Modular-Arithmetic-1" class="headerlink" title="Modular Arithmetic 1"></a>Modular Arithmetic 1</h2><h3 id="Description-2"><a href="#Description-2" class="headerlink" title="Description"></a>Description</h3><p>Imagine you lean over and look at a cryptographer’s notebook. You see some notes in the margin:</p><figure class="highlight basic"><table><tr><td class="code"><pre><span class="line"><span class="symbol">4 </span>+ <span class="number">9</span> = <span class="number">1</span></span><br><span class="line"><span class="symbol">5 </span>- <span class="number">7</span> = <span class="number">10</span></span><br><span class="line"><span class="symbol">2 </span>+ <span class="number">3</span> = <span class="number">5</span></span><br></pre></td></tr></table></figure><p>At first you might think they’ve gone mad. Maybe this is why there are so many data leaks nowadays you’d think, but this is nothing more than modular arithmetic modulo 12 (albeit with some sloppy notation).</p><p>You may not have been calling it modular arithmetic, but you’ve been doing these kinds of calculations since you learnt to tell the time (look again at those equations and think about adding hours).</p><p>Formally, “calculating time” is described by the theory of congruences. We say that two integers are congruent modulo m if <code>a ≡ b mod m</code>.</p><p>Another way of saying this, is that when we divide the integer <code>a</code> by <code>m</code>, the remainder is <code>b</code>. This tells you that if m divides a (this can be written as <code>m | a</code>) then <code>a ≡ 0 mod m</code>.</p><p>Calculate the following integers:</p><figure class="highlight basic"><table><tr><td class="code"><pre><span class="line"><span class="symbol">11 </span>≡ x <span class="keyword">mod</span> <span class="number">6</span></span><br><span class="line"><span class="symbol">8146798528947 </span>≡ y <span class="keyword">mod</span> <span class="number">17</span></span><br></pre></td></tr></table></figure><p>The solution is the smaller of the two integers.</p><h3 id="Analyze-2"><a href="#Analyze-2" class="headerlink" title="Analyze"></a>Analyze</h3><p>模运算来了，头大。后面全是和模运算有关的（准确来说这一整章都是</p><p>这道算简单，取余算一下 x 和 y，然后按要求输出小的。没啥好思考的捏。</p><h3 id="Code-2"><a href="#Code-2" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">n = <span class="number">8146798528947</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">min</span>(n % <span class="number">17</span>, <span class="number">11</span> % <span class="number">6</span>))</span><br></pre></td></tr></table></figure><h2 id="Modular-Arithmetic-2"><a href="#Modular-Arithmetic-2" class="headerlink" title="Modular Arithmetic 2"></a>Modular Arithmetic 2</h2><h3 id="Description-3"><a href="#Description-3" class="headerlink" title="Description"></a>Description</h3><p>We’ll pick up from the last challenge and imagine we’ve picked a modulus <code>p</code>, and we will restrict ourselves to the case when <code>p</code> is prime.</p><p>The integers modulo <code>p</code> define a field, denoted <code>Fp</code>.</p><blockquote><p>If the modulus is not prime, the set of integers modulo <code>n</code> define a ring.</p></blockquote><p>A finite field <code>Fp</code> is the set of integers <code>&#123;0,1,...,p-1&#125;</code>, and under both addition and multiplication there is an inverse element <code>b</code> for every element <code>a</code> in the set, such that <code>a + b = 0</code> and <code>a * b = 1</code>.</p><blockquote><p>Note that the identity element for addition and multiplication is different! This is because the identity when acted with the operator should do nothing: <code>a + 0 = a</code> and <code>a * 1 = a</code>.</p></blockquote><p>Lets say we pick <code>p = 17</code>. Calculate <code>317 mod 17</code>. Now do the same but with <code>517 mod 17</code>.</p><p>What would you expect to get for <code>716 mod 17</code>? Try calculating that.</p><p>This interesting fact is known as Fermat’s little theorem. We’ll be needing this (and its generalisations) when we look at RSA cryptography.</p><p>Now take the prime <code>p = 65537</code>. Calculate <code>27324678765465536 mod 65537</code>.</p><p>Did you need a calculator?</p><h3 id="Analyze-3"><a href="#Analyze-3" class="headerlink" title="Analyze"></a>Analyze</h3><p>费马小定理，蛮有意思的一个公式。</p><p>$a^{p} \equiv a \mod p$，浅浅变形一下：$a^{p-1} \equiv 1 \mod p$</p><p>主要题目描述这个定理的时候略微有一点写复杂咯，不够优雅（ bushi。</p><p>这么推导出来其实没有写代码的必要。</p><h3 id="Code-3"><a href="#Code-3" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">a = <span class="number">273246787654</span></span><br><span class="line">p = <span class="number">65537</span></span><br><span class="line"><span class="built_in">print</span>(<span class="number">1</span> % p)</span><br><span class="line"></span><br><span class="line"><span class="comment"># a^(p-1) ≡ 1(mod p)</span></span><br></pre></td></tr></table></figure><h2 id="Modular-Inverting"><a href="#Modular-Inverting" class="headerlink" title="Modular Inverting"></a>Modular Inverting</h2><h3 id="Description-4"><a href="#Description-4" class="headerlink" title="Description"></a>Description</h3><p>As we’ve seen, we can work within a finite field <code>Fp</code>, adding and multiplying elements, and always obtain another element of the field.</p><p>For all elements <code>g</code> in the field, there exists a unique integer <code>d</code> such that <code>g * d ≡ 1 mod p</code>.</p><p>This is the multiplicative inverse of <code>g</code>.</p><p><strong>Example</strong>: <code>7 * 8 = 56 ≡ 1 mod 11</code></p><p>What is the inverse element: <code>3 * d ≡ 1 mod 13</code>?</p><blockquote><p>Think about the little theorem we just worked with. How does this help you find the inverse of an element?</p></blockquote><h3 id="Analyze-4"><a href="#Analyze-4" class="headerlink" title="Analyze"></a>Analyze</h3><p>模逆运算，同余这块的知识。主要是欧拉定理和费马小定理的应用。</p><p>欧拉定理：$a^{φ(n)} \equiv 1 \mod n$</p><p>费马小定理：$a^{p-1} \equiv 1 \mod p$</p><p>对于这道题，有 $3 * d \equiv 1 \mod 13$</p><p>因为 gcd(3, 13) = 1，所以可以直接得<script type="math/tex">d\ =\ 3^{φ(13)-1}\ *\ 1=3^{11} \mod 13</script> </p><p>python 的 pow() 函数真的很好用！</p><h3 id="Code-4"><a href="#Code-4" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">d = <span class="built_in">pow</span> (<span class="number">3</span>, <span class="number">11</span>, <span class="number">13</span>)</span><br><span class="line"><span class="built_in">print</span>(d)</span><br></pre></td></tr></table></figure><h3 id="SumUp-2"><a href="#SumUp-2" class="headerlink" title="SumUp"></a>SumUp</h3><p>$φ(n)$ 即 <code>1 ~ (n-1)</code> 范围内与 n 互素的数的个数，若 n 本身为素数，则 $φ(n)=n-1$ 。</p><h2 id="Quadratic-Residues"><a href="#Quadratic-Residues" class="headerlink" title="Quadratic Residues"></a>Quadratic Residues</h2><h3 id="Description-5"><a href="#Description-5" class="headerlink" title="Description"></a>Description</h3><p>We’ve looked at multiplication and division in modular arithmetic, but what does it mean to take the square root modulo an integer?</p><p>For the following discussion, let’s work modulo <code>p = 29</code>. We can take the integer <code>a = 11</code> and calculate <code>a² = 5 mod 29</code>.</p><p>As <code>a = 11, a² = 5</code>, we say the square root of <code>5</code> is <code>11</code>.</p><p>This feels good, but now let’s think about the square root of <code>18</code>. From the above, we know we need to find some integer <code>a</code> such that <code>a² = 18</code></p><p>Your first idea might be to start with <code>a = 1</code> and loop to <code>a = p-1</code>. In this discussion <code>p</code> isn’t too large and we can quickly look.</p><p>Have a go, try coding this and see what you find. If you’ve coded it right, you’ll find that for all <code>a ∈ Fp*</code> you never find an <code>a</code> such that <code>a² = 18</code>.</p><p>What we are seeing, is that for the elements of <code>F*p</code>, not every element has a square root. In fact, what we find is that for roughly one half of the elements of <code>Fp*</code>, there is no square root.</p><blockquote><p>We say that an integer <code>x</code> is a <em>Quadratic Residue</em> if there exists an <code>a</code> such that <code>a² = x mod p</code>. If there is no such solution, then the integer is a <em>Quadratic Non-Residue</em>.</p></blockquote><p>In other words, <code>x</code> is a quadratic residue when it is possible to take the square root of <code>x</code> modulo an integer <code>p</code>.</p><p>In the below list there are two non-quadratic residues and one quadratic residue.</p><p>Find the quadratic residue and then calculate its square root. Of the two possible roots, submit the smaller one as the flag.</p><blockquote><p>If <code>a² = x</code> then (-a)² = x. So if <code>x</code> is a quadratic residue in some finite field, then there are always two solutions for <code>a</code>.</p></blockquote><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="attr">p</span> = <span class="number">29</span></span><br><span class="line"><span class="attr">ints</span> = [<span class="number">14</span>, <span class="number">6</span>, <span class="number">11</span>]</span><br></pre></td></tr></table></figure><h3 id="Analyze-5"><a href="#Analyze-5" class="headerlink" title="Analyze"></a>Analyze</h3><p>Legendre 符号（欧拉判别法）的内容，二次剩余。</p><p>定义：如果 $a^2 \equiv x \mod p$ 有解，则 x 是模 p 的二次剩余，否则称为二次非剩余,。</p><p>Given: p, x[]</p><p>Asked: 找出二次剩余，并求出平方根。</p><p>遍历 x in range(1, p)，计算 x 的平方模 p，并与 ints[] 中的元素进行比较，找出模 p 的二次剩余，此时的 x 即为该二次剩余的平方根。</p><p>公式和题里的 a 和 x 参数真的很容易弄混，理了半天才理清楚 。。</p><h3 id="Code-5"><a href="#Code-5" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">p = <span class="number">29</span></span><br><span class="line">ints = [<span class="number">14</span>, <span class="number">6</span>, <span class="number">11</span>]</span><br><span class="line">flag = <span class="built_in">min</span>(x <span class="keyword">for</span> x <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">1</span>, p) <span class="keyword">if</span> <span class="built_in">pow</span>(x, <span class="number">2</span>, p) <span class="keyword">in</span> ints)</span><br><span class="line"><span class="built_in">print</span>(flag)</span><br></pre></td></tr></table></figure><h2 id="Legendre-Symbol"><a href="#Legendre-Symbol" class="headerlink" title="Legendre Symbol"></a>Legendre Symbol</h2><h3 id="Description-6"><a href="#Description-6" class="headerlink" title="Description"></a>Description</h3><p>In Quadratic Residues we learnt what it means to take the square root modulo an integer. We also saw that taking a root isn’t always possible.</p><p>In the previous case when <code>p = 29</code>, even the simplest method of calculating the square root was fast enough, but as <code>p</code> gets larger, this method becomes wildly unreasonable.</p><p>Lucky for us, we have a way to check whether an integer is a quadratic residue with a single calculation thanks to Legendre. In the following, we will assume we are working modulo a prime <code>p</code>.</p><p>Before looking at Legendre’s symbol, let’s take a brief detour to see an interesting property of quadratic (non-)residues.</p><figure class="highlight mathematica"><table><tr><td class="code"><pre><span class="line"><span class="variable">Quadratic</span> <span class="built_in">Residue</span> <span class="operator">*</span> <span class="variable">Quadratic</span> <span class="built_in">Residue</span> <span class="operator">=</span> <span class="variable">Quadratic</span> <span class="built_in">Residue</span></span><br><span class="line"><span class="variable">Quadratic</span> <span class="built_in">Residue</span> <span class="operator">*</span> <span class="variable">Quadratic</span> <span class="variable">Non</span><span class="operator">-</span><span class="variable">residue</span> <span class="operator">=</span> <span class="variable">Quadratic</span> <span class="variable">Non</span><span class="operator">-</span><span class="variable">residue</span></span><br><span class="line"><span class="variable">Quadratic</span> <span class="variable">Non</span><span class="operator">-</span><span class="variable">residue</span> <span class="operator">*</span> <span class="variable">Quadratic</span> <span class="variable">Non</span><span class="operator">-</span><span class="variable">residue</span> <span class="operator">=</span> <span class="variable">Quadratic</span> <span class="built_in">Residue</span></span><br></pre></td></tr></table></figure><blockquote><p>Want an easy way to remember this? Replace “Quadratic Residue” with <code>+1</code> and “Quadratic Non-residue” with <code>-1</code>, all three results are the same!</p></blockquote><p>So what’s the trick? The <a href="https://en.wikipedia.org/wiki/Legendre_symbol">Legendre Symbol</a> gives an efficient way to determine whether an integer is a quadratic residue modulo an odd prime <code>p</code>.</p><p>Legendre’s Symbol: <code>(a / p) ≡ a(p-1)/2 mod p</code> obeys:</p><figure class="highlight stylus"><table><tr><td class="code"><pre><span class="line">(<span class="selector-tag">a</span> / p) = <span class="number">1</span> <span class="keyword">if</span> <span class="selector-tag">a</span> is <span class="selector-tag">a</span> quadratic residue and <span class="selector-tag">a</span> ≢ <span class="number">0</span> mod <span class="selector-tag">p</span></span><br><span class="line">(<span class="selector-tag">a</span> / p) = -<span class="number">1</span> <span class="keyword">if</span> <span class="selector-tag">a</span> is <span class="selector-tag">a</span> quadratic non-residue mod <span class="selector-tag">p</span></span><br><span class="line">(<span class="selector-tag">a</span> / p) = <span class="number">0</span> <span class="keyword">if</span> <span class="selector-tag">a</span> ≡ <span class="number">0</span> mod p</span><br></pre></td></tr></table></figure><p>Which means given any integer <code>a</code>, calculating <code>pow(a,(p-1)/2,p)</code> is enough to determine if <code>a</code> is a quadratic residue.</p><p>Now for the flag. Given the following 1024 bit prime and 10 integers, find the quadratic residue and then calculate its square root; the square root is your flag. Of the two possible roots, submit the larger one as your answer.</p><blockquote><p>So Legendre’s symbol tells us which integer is a quadratic residue, but how do we find the square root?! The prime supplied obeys <code>p = 3 mod 4</code>, which allows us easily compute the square root. The answer is online, but you can figure it out yourself if you think about Fermat’s little theorem.</p></blockquote><h3 id="Analyze-6"><a href="#Analyze-6" class="headerlink" title="Analyze"></a>Analyze</h3><p>Legendre 符号的欧拉判别法。</p><script type="math/tex; mode=display">\left(\frac{a}{p}\right)=\begin{cases}1, &a ≢ 0 \mod p\text{ 且 }a\text{ 是模 }p\text{ 的二次剩余} \\\ -1, &a ≢ 0 \mod p\text{ 且 }a\text{ 是模 }p\text{ 的二次非剩余} \\\ 0, &a ≡0 \mod p \end{cases}</script><p>欧拉判别法内容：$(a/p) \equiv a^{(p-1)/2} \mod p$。</p><p>遍历 ints 判断各自对应的 $(a/p)$ 是否等于 1，得到二次剩余 a 之后计算平方根 $a^{(p+1)/4} \mod p$ 。</p><h3 id="Code-6"><a href="#Code-6" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">p = <span class="number">101524035174539890485408575671085261788758965189060164484385690801466167356667036677932998889725476582421738788500738738503134356158197247473850273565349249573867251280253564698939768700489401960767007716413932851838937641880157263936985954881657889497583485535527613578457628399173971810541670838543309159139</span></span><br><span class="line">ints = [<span class="number">25081841204695904475894082974192007718642931811040324543182130088804239047149283334700530600468528298920930150221871666297194395061462592781551275161695411167049544771049769000895119729307495913024360169904315078028798025169985966732789207320203861858234048872508633514498384390497048416012928086480326832803</span>, <span class="number">45471765180330439060504647480621449634904192839383897212809808339619841633826534856109999027962620381874878086991125854247108359699799913776917227058286090426484548349388138935504299609200377899052716663351188664096302672712078508601311725863678223874157861163196340391008634419348573975841578359355931590555</span>, <span class="number">17364140182001694956465593533200623738590196990236340894554145562517924989208719245429557645254953527658049246737589538280332010533027062477684237933221198639948938784244510469138826808187365678322547992099715229218615475923754896960363138890331502811292427146595752813297603265829581292183917027983351121325</span>, <span class="number">14388109104985808487337749876058284426747816961971581447380608277949200244660381570568531129775053684256071819837294436069133592772543582735985855506250660938574234958754211349215293281645205354069970790155237033436065434572020652955666855773232074749487007626050323967496732359278657193580493324467258802863</span>, <span class="number">4379499308310772821004090447650785095356643590411706358119239166662089428685562719233435615196994728767593223519226235062647670077854687031681041462632566890129595506430188602238753450337691441293042716909901692570971955078924699306873191983953501093343423248482960643055943413031768521782634679536276233318</span>, <span class="number">85256449776780591202928235662805033201684571648990042997557084658000067050672130152734911919581661523957075992761662315262685030115255938352540032297113615687815976039390537716707854569980516690246592112936796917504034711418465442893323439490171095447109457355598873230115172636184525449905022174536414781771</span>, <span class="number">50576597458517451578431293746926099486388286246142012476814190030935689430726042810458344828563913001012415702876199708216875020997112089693759638454900092580746638631062117961876611545851157613835724635005253792316142379239047654392970415343694657580353333217547079551304961116837545648785312490665576832987</span>, <span class="number">96868738830341112368094632337476840272563704408573054404213766500407517251810212494515862176356916912627172280446141202661640191237336568731069327906100896178776245311689857997012187599140875912026589672629935267844696976980890380730867520071059572350667913710344648377601017758188404474812654737363275994871</span>, <span class="number">4881261656846638800623549662943393234361061827128610120046315649707078244180313661063004390750821317096754282796876479695558644108492317407662131441224257537276274962372021273583478509416358764706098471849536036184924640593888902859441388472856822541452041181244337124767666161645827145408781917658423571721</span>, <span class="number">18237936726367556664171427575475596460727369368246286138804284742124256700367133250078608537129877968287885457417957868580553371999414227484737603688992620953200143688061024092623556471053006464123205133894607923801371986027458274343737860395496260538663183193877539815179246700525865152165600985105257601565</span>]</span><br><span class="line"></span><br><span class="line">res = [x <span class="keyword">for</span> x <span class="keyword">in</span> ints <span class="keyword">if</span> <span class="built_in">pow</span>(x, (p-<span class="number">1</span>)//<span class="number">2</span>, p) == <span class="number">1</span>][<span class="number">0</span>]</span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">pow</span>(res, (p + <span class="number">1</span>)//<span class="number">4</span>, p))</span><br></pre></td></tr></table></figure><h2 id="Modular-Square-Root"><a href="#Modular-Square-Root" class="headerlink" title="Modular Square Root"></a>Modular Square Root</h2><h3 id="Description-7"><a href="#Description-7" class="headerlink" title="Description"></a>Description</h3><p>In Legendre Symbol we introduced a fast way to determine whether a number is a square root modulo a prime. We can go further: there are algorithms for efficiently calculating such roots. The best one in practice is called Tonelli-Shanks, which gets its funny name from the fact that it was first described by an Italian in the 19th century and rediscovered independently by Daniel Shanks in the 1970s.</p><p>All primes that aren’t 2 are of the form <code>p ≡ 1 mod 4</code> or <code>p ≡ 3 mod 4</code>, since all odd numbers obey these congruences. As the previous challenge hinted, in the <code>p ≡ 3 mod 4</code> case, a really simple formula for computing square roots can be <a href="https://crypto.stackexchange.com/a/20994">derived</a> directly from Fermat’s little theorem. That leaves us still with the <code>p ≡ 1 mod 4</code> case, so a more general algorithm is required.</p><p>In a congruence of the form <code>r² ≡ a mod p</code>, Tonelli-Shanks calculates <code>r</code>.</p><blockquote><p>Tonelli-Shanks doesn’t work for composite (non-prime) moduli. Finding square roots modulo composites is computationally equivalent to integer factorization.</p></blockquote><p>The main use-case for this algorithm is finding elliptic curve co-ordinates. Its operation is somewhat complex so we’re not going to discuss the details, however, implementations are easy to find and Sage has one built-in.</p><p>Find the square root of <code>a</code> modulo the 2048-bit prime <code>p</code>. Give the smaller of the two roots as your answer.</p><h3 id="Analyze-7"><a href="#Analyze-7" class="headerlink" title="Analyze"></a>Analyze</h3><p>sympy 模块内有封装好的函数可以计算二次剩余。</p><p>函数 nthroot_mod(a, n, p) 用于求解于 $x^{n} \equiv a\ mod\ p$ 的同余式。</p><p>题目给了表达式 $r^2 \equiv a\ mod\ p$，求 r。</p><p>写了半天函数心态爆炸，然后搜了下 python 相关的库，几行就解决。</p><p>再次感叹，python 真是个好东西。</p><h3 id="Code-7"><a href="#Code-7" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> sympy</span><br><span class="line">a = <span class="number">8479994658316772151941616510097127087554541274812435112009425778595495359700244470400642403747058566807127814165396640215844192327900454116257979487432016769329970767046735091249898678088061634796559556704959846424131820416048436501387617211770124292793308079214153179977624440438616958575058361193975686620046439877308339989295604537867493683872778843921771307305602776398786978353866231661453376056771972069776398999013769588936194859344941268223184197231368887060609212875507518936172060702209557124430477137421847130682601666968691651447236917018634902407704797328509461854842432015009878011354022108661461024768</span></span><br><span class="line">p = <span class="number">30531851861994333252675935111487950694414332763909083514133769861350960895076504687261369815735742549428789138300843082086550059082835141454526618160634109969195486322015775943030060449557090064811940139431735209185996454739163555910726493597222646855506445602953689527405362207926990442391705014604777038685880527537489845359101552442292804398472642356609304810680731556542002301547846635101455995732584071355903010856718680732337369128498655255277003643669031694516851390505923416710601212618443109844041514942401969629158975457079026906304328749039997262960301209158175920051890620947063936347307238412281568760161</span></span><br><span class="line">r = sympy.nthroot_mod(a, <span class="number">2</span>, p)</span><br><span class="line"><span class="built_in">print</span>(r)</span><br></pre></td></tr></table></figure><h3 id="SumUp-3"><a href="#SumUp-3" class="headerlink" title="SumUp"></a>SumUp</h3><p>$x^{n} \equiv a\ mod\ p$，求 x</p><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># function:</span></span><br><span class="line"><span class="keyword">from</span> sympy.ntheory.residue_ntheory <span class="keyword">import</span> nthroot_mod</span><br><span class="line">x = nthroot_mod(a, n, p)</span><br></pre></td></tr></table></figure><h2 id="Chinese-Remainder-Theorem"><a href="#Chinese-Remainder-Theorem" class="headerlink" title="Chinese Remainder Theorem"></a>Chinese Remainder Theorem</h2><h3 id="Description-8"><a href="#Description-8" class="headerlink" title="Description"></a>Description</h3><p>The Chinese Remainder Theorem gives a unique solution to a set of linear congruences if their moduli are coprime.</p><p>This means, that given a set of arbitrary integers <code>ai</code>, and pairwise coprime integers <code>ni</code>, such that the following linear congruences hold:</p><blockquote><p>Note “pairwise coprime integers” means that if we have a set of integers <code>&#123;n1, n2, ..., ni&#125;</code>, all pairs of integers selected from the set are coprime: <code>gcd(ni, nj) = 1</code>.</p></blockquote><figure class="highlight livecodeserver"><table><tr><td class="code"><pre><span class="line">x ≡ a1 <span class="keyword">mod</span> n1</span><br><span class="line">x ≡ a2 <span class="keyword">mod</span> n2</span><br><span class="line">...</span><br><span class="line">x ≡ <span class="keyword">an</span> <span class="keyword">mod</span> nn</span><br></pre></td></tr></table></figure><p>There is a unique solution <code>x ≡ a mod N</code> where <code>N = n1 * n2 * ... * nn</code>.</p><p>In cryptography, we commonly use the Chinese Remainder Theorem to help us reduce a problem of very large integers into a set of several, easier problems.</p><p>Given the following set of linear congruences:</p><figure class="highlight apache"><table><tr><td class="code"><pre><span class="line"><span class="attribute">x</span> ≡ <span class="number">2</span> mod <span class="number">5</span></span><br><span class="line"><span class="attribute">x</span> ≡ <span class="number">3</span> mod <span class="number">11</span></span><br><span class="line"><span class="attribute">x</span> ≡ <span class="number">5</span> mod <span class="number">17</span></span><br></pre></td></tr></table></figure><p>Find the integer <code>a</code> such that <code>x ≡ a mod 935</code></p><blockquote><p>Starting with the congruence with the largest modulus, use that for <code>x ≡ a mod p</code> we can write <code>x = a + k*p</code> for arbitrary integer <code>k</code>.</p></blockquote><h3 id="Analyze-8"><a href="#Analyze-8" class="headerlink" title="Analyze"></a>Analyze</h3><p>中国剩余定理，也叫孙子定理。主要针对同余方程组的求解问题。</p><p>YouTube 上找了个视频看了原理，跟着视频手算出来了结果，感觉跟着例题一步步算真的能加深理解诶，很容易就理解到了原理和用法。</p><p><img src="https://img.hawa130.com/求解过程.jpg" alt="求解过程"></p><p>算法直接找了个板子，偷个懒捏。</p><h3 id="Code-8"><a href="#Code-8" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> functools <span class="keyword">import</span> reduce</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">chinese_remainder</span>(<span class="params">n, a</span>):</span><br><span class="line">    <span class="built_in">sum</span> = <span class="number">0</span></span><br><span class="line">    prod = reduce(<span class="keyword">lambda</span> a, b: a * b, n)</span><br><span class="line">    <span class="keyword">for</span> n_i, a_i <span class="keyword">in</span> <span class="built_in">zip</span>(n, a):</span><br><span class="line">        p = prod // n_i</span><br><span class="line">        <span class="built_in">sum</span> += a_i * mul_inv(p, n_i) * p</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">sum</span> % prod</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">mul_inv</span>(<span class="params">a, b</span>):</span><br><span class="line">    b0 = b</span><br><span class="line">    x0, x1 = <span class="number">0</span>, <span class="number">1</span></span><br><span class="line">    <span class="keyword">if</span> b == <span class="number">1</span>:</span><br><span class="line">        <span class="keyword">return</span> <span class="number">1</span></span><br><span class="line">    <span class="keyword">while</span> a &gt; <span class="number">1</span>:</span><br><span class="line">        q = a // b</span><br><span class="line">        a, b = b, a % b</span><br><span class="line">        x0, x1 = x1 - q * x0, x0</span><br><span class="line">    <span class="keyword">if</span> x1 &lt; <span class="number">0</span>:</span><br><span class="line">        x1 += b0</span><br><span class="line">    <span class="keyword">return</span> x1</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">n = [<span class="number">5</span>, <span class="number">11</span>, <span class="number">17</span>]</span><br><span class="line">a = [<span class="number">2</span>, <span class="number">3</span>, <span class="number">5</span>]</span><br><span class="line"><span class="built_in">print</span>(chinese_remainder(n, a))</span><br></pre></td></tr></table></figure><h2 id="Adrien’s-Signs"><a href="#Adrien’s-Signs" class="headerlink" title="Adrien’s Signs"></a>Adrien’s Signs</h2><h3 id="Description-9"><a href="#Description-9" class="headerlink" title="Description"></a>Description</h3><p>Adrien’s been looking at ways to encrypt his messages with the help of symbols and minus signs. Can you find a way to recover the flag?</p><h3 id="Analyze-9"><a href="#Analyze-9" class="headerlink" title="Analyze"></a>Analyze</h3><p>python 学得不好，加密函数理解了好久。</p><p>解密倒还好，拿到密文直接正常取对数，取不到就负数取余把 n 还原回去再取对数。</p><p>不过代码得跑一会才能出结果，后面或许可以再看看有没有更优解。</p><p>（最后一行的代码简直写得太优雅咯</p><h3 id="Code-9"><a href="#Code-9" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> numpy <span class="keyword">import</span> arange</span><br><span class="line"><span class="keyword">from</span> sympy <span class="keyword">import</span> discrete_log</span><br><span class="line"></span><br><span class="line">lis = [<span class="number">67594220461269</span>, <span class="number">501237540280788</span>, <span class="number">718316769824518</span>, <span class="number">296304224247167</span>, <span class="number">48290626940198</span>, <span class="number">30829701196032</span>, <span class="number">521453693392074</span>, <span class="number">840985324383794</span>, <span class="number">770420008897119</span>, <span class="number">745131486581197</span>, <span class="number">729163531979577</span>, <span class="number">334563813238599</span>, <span class="number">289746215495432</span>, <span class="number">538664937794468</span>, <span class="number">894085795317163</span>, <span class="number">983410189487558</span>, <span class="number">863330928724430</span>, <span class="number">996272871140947</span>, <span class="number">352175210511707</span>, <span class="number">306237700811584</span>, <span class="number">631393408838583</span>, <span class="number">589243747914057</span>, <span class="number">538776819034934</span>, <span class="number">365364592128161</span>, <span class="number">454970171810424</span>, <span class="number">986711310037393</span>, <span class="number">657756453404881</span>, <span class="number">388329936724352</span>, <span class="number">90991447679370</span>, <span class="number">714742162831112</span>, <span class="number">62293519842555</span>, <span class="number">653941126489711</span>, <span class="number">448552658212336</span>, <span class="number">970169071154259</span>, <span class="number">339472870407614</span>, <span class="number">406225588145372</span>, <span class="number">205721593331090</span>, <span class="number">926225022409823</span>, <span class="number">904451547059845</span>, <span class="number">789074084078342</span>, <span class="number">886420071481685</span>, <span class="number">796827329208633</span>, <span class="number">433047156347276</span>, <span class="number">21271315846750</span>, <span class="number">719248860593631</span>, <span class="number">534059295222748</span>, <span class="number">879864647580512</span>, <span class="number">918055794962142</span>, <span class="number">635545050939893</span>, <span class="number">319549343320339</span>, <span class="number">93008646178282</span>, <span class="number">926080110625306</span>, <span class="number">385476640825005</span>, <span class="number">483740420173050</span>, <span class="number">866208659796189</span>, <span class="number">883359067574584</span>, <span class="number">913405110264883</span>, <span class="number">898864873510337</span>, <span class="number">208598541987988</span>, <span class="number">23412800024088</span>, <span class="number">911541450703474</span>, <span class="number">57446699305445</span>, <span class="number">513296484586451</span>, <span class="number">180356843554043</span>, <span class="number">756391301483653</span>, <span class="number">823695939808936</span>, <span class="number">452898981558365</span>, <span class="number">383286682802447</span>, <span class="number">381394258915860</span>, <span class="number">385482809649632</span>, <span class="number">357950424436020</span>, <span class="number">212891024562585</span>, <span class="number">906036654538589</span>, <span class="number">706766032862393</span>, <span class="number">500658491083279</span>, <span class="number">134746243085697</span>, <span class="number">240386541491998</span>, <span class="number">850341345692155</span>, <span class="number">826490944132718</span>, <span class="number">329513332018620</span>, <span class="number">41046816597282</span>, <span class="number">396581286424992</span>, <span class="number">488863267297267</span>, <span class="number">92023040998362</span>, <span class="number">529684488438507</span>, <span class="number">925328511390026</span>, <span class="number">524897846090435</span>, <span class="number">413156582909097</span>, <span class="number">840524616502482</span>, <span class="number">325719016994120</span>, <span class="number">402494835113608</span>, <span class="number">145033960690364</span>, <span class="number">43932113323388</span>, <span class="number">683561775499473</span>, <span class="number">434510534220939</span>, <span class="number">92584300328516</span>, <span class="number">763767269974656</span>, <span class="number">289837041593468</span>, <span class="number">11468527450938</span>, <span class="number">628247946152943</span>, <span class="number">8844724571683</span>, <span class="number">813851806959975</span>, <span class="number">72001988637120</span>, <span class="number">875394575395153</span>, <span class="number">70667866716476</span>, <span class="number">75304931994100</span>, <span class="number">226809172374264</span>, <span class="number">767059176444181</span>, <span class="number">45462007920789</span>, <span class="number">472607315695803</span>, <span class="number">325973946551448</span>, <span class="number">64200767729194</span>, <span class="number">534886246409921</span>, <span class="number">950408390792175</span>, <span class="number">492288777130394</span>, <span class="number">226746605380806</span>, <span class="number">944479111810431</span>, <span class="number">776057001143579</span>, <span class="number">658971626589122</span>, <span class="number">231918349590349</span>, <span class="number">699710172246548</span>, <span class="number">122457405264610</span>, <span class="number">643115611310737</span>, <span class="number">999072890586878</span>, <span class="number">203230862786955</span>, <span class="number">348112034218733</span>, <span class="number">240143417330886</span>, <span class="number">927148962961842</span>, <span class="number">661569511006072</span>, <span class="number">190334725550806</span>, <span class="number">763365444730995</span>, <span class="number">516228913786395</span>, <span class="number">846501182194443</span>, <span class="number">741210200995504</span>, <span class="number">511935604454925</span>, <span class="number">687689993302203</span>, <span class="number">631038090127480</span>, <span class="number">961606522916414</span>, <span class="number">138550017953034</span>, <span class="number">932105540686829</span>, <span class="number">215285284639233</span>, <span class="number">772628158955819</span>, <span class="number">496858298527292</span>, <span class="number">730971468815108</span>, <span class="number">896733219370353</span>, <span class="number">967083685727881</span>, <span class="number">607660822695530</span>, <span class="number">650953466617730</span>, <span class="number">133773994258132</span>, <span class="number">623283311953090</span>, <span class="number">436380836970128</span>, <span class="number">237114930094468</span>, <span class="number">115451711811481</span>, <span class="number">674593269112948</span>, <span class="number">140400921371770</span>, <span class="number">659335660634071</span>, <span class="number">536749311958781</span>, <span class="number">854645598266824</span>, <span class="number">303305169095255</span>, <span class="number">91430489108219</span>, <span class="number">573739385205188</span>, <span class="number">400604977158702</span>, <span class="number">728593782212529</span>, <span class="number">807432219147040</span>, <span class="number">893541884126828</span>, <span class="number">183964371201281</span>, <span class="number">422680633277230</span>, <span class="number">218817645778789</span>, <span class="number">313025293025224</span>, <span class="number">657253930848472</span>, <span class="number">747562211812373</span>, <span class="number">83456701182914</span>, <span class="number">470417289614736</span>, <span class="number">641146659305859</span>, <span class="number">468130225316006</span>, <span class="number">46960547227850</span>, <span class="number">875638267674897</span>, <span class="number">662661765336441</span>, <span class="number">186533085001285</span>, <span class="number">743250648436106</span>, <span class="number">451414956181714</span>, <span class="number">527954145201673</span>, <span class="number">922589993405001</span>, <span class="number">242119479617901</span>, <span class="number">865476357142231</span>, <span class="number">988987578447349</span>, <span class="number">430198555146088</span>, <span class="number">477890180119931</span>, <span class="number">844464003254807</span>, <span class="number">503374203275928</span>, <span class="number">775374254241792</span>, <span class="number">346653210679737</span>, <span class="number">789242808338116</span>, <span class="number">48503976498612</span>, <span class="number">604300186163323</span>, <span class="number">475930096252359</span>, <span class="number">860836853339514</span>, <span class="number">994513691290102</span>, <span class="number">591343659366796</span>, <span class="number">944852018048514</span>, <span class="number">82396968629164</span>, <span class="number">152776642436549</span>, <span class="number">916070996204621</span>, <span class="number">305574094667054</span>, <span class="number">981194179562189</span>, <span class="number">126174175810273</span>, <span class="number">55636640522694</span>, <span class="number">44670495393401</span>, <span class="number">74724541586529</span>, <span class="number">988608465654705</span>, <span class="number">870533906709633</span>, <span class="number">374564052429787</span>, <span class="number">486493568142979</span>, <span class="number">469485372072295</span>, <span class="number">221153171135022</span>, <span class="number">289713227465073</span>, <span class="number">952450431038075</span>, <span class="number">107298466441025</span>, <span class="number">938262809228861</span>, <span class="number">253919870663003</span>, <span class="number">835790485199226</span>, <span class="number">655456538877798</span>, <span class="number">595464842927075</span>, <span class="number">191621819564547</span>]</span><br><span class="line">a = <span class="number">288260533169915</span></span><br><span class="line">p = <span class="number">1007621497415251</span></span><br><span class="line">decode = <span class="string">&#x27;&#x27;</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> arange(<span class="built_in">len</span>(lis)):</span><br><span class="line">    cipher = lis[i]</span><br><span class="line">    <span class="keyword">try</span>:</span><br><span class="line">        r = discrete_log(p, cipher, a)</span><br><span class="line">        decode += <span class="string">&#x27;1&#x27;</span></span><br><span class="line">    <span class="keyword">except</span>:</span><br><span class="line">        r = discrete_log(p, -cipher % p, a)</span><br><span class="line">        decode += <span class="string">&#x27;0&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;&#x27;</span>.join([<span class="built_in">chr</span>(<span class="built_in">int</span>(decode[i:i+<span class="number">8</span>], <span class="number">2</span>)) <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">0</span>, <span class="built_in">len</span>(decode), <span class="number">8</span>)]))</span><br></pre></td></tr></table></figure><h2 id="Modular-Binomials"><a href="#Modular-Binomials" class="headerlink" title="Modular Binomials"></a>Modular Binomials</h2><h3 id="Description-10"><a href="#Description-10" class="headerlink" title="Description"></a>Description</h3><p>Rearrange the following equations to get <code>p,q</code></p><figure class="highlight ini"><table><tr><td class="code"><pre><span class="line"><span class="attr">N</span> = p*q</span><br><span class="line"><span class="attr">c1</span> = (<span class="number">2</span>*p + <span class="number">3</span>*q)**e1 mod N</span><br><span class="line"><span class="attr">c2</span> = (<span class="number">5</span>*p + <span class="number">7</span>*q)**e2 mod N</span><br></pre></td></tr></table></figure><h3 id="Analyze-10"><a href="#Analyze-10" class="headerlink" title="Analyze"></a>Analyze</h3><p>给了五个参数，求两个未知数 p 和 q，一眼看到给了 p，q 的乘积 N，所以只要随便求出来其中一个然后除 N 就可以咯。</p><p>我是先求了 q，所以先把两个方程右边配成齐次的，然后把要消掉的 p 的系数配成一样的，q 的系数刚好是 15 和 14，相减就是 q 咯。</p><p>最后一道题倒是没啥技术含量，就嗯解方程组。</p><h3 id="Code-10"><a href="#Code-10" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> math</span><br><span class="line">N = <span class="number">14905562257842714057932724129575002825405393502650869767115942606408600343380327866258982402447992564988466588305174271674657844352454543958847568190372446723549627752274442789184236490768272313187410077124234699854724907039770193680822495470532218905083459730998003622926152590597710213127952141056029516116785229504645179830037937222022291571738973603920664929150436463632305664687903244972880062028301085749434688159905768052041207513149370212313943117665914802379158613359049957688563885391972151218676545972118494969247440489763431359679770422939441710783575668679693678435669541781490217731619224470152467768073</span></span><br><span class="line">e1 = <span class="number">12886657667389660800780796462970504910193928992888518978200029826975978624718627799215564700096007849924866627154987365059524315097631111242449314835868137</span></span><br><span class="line">e2 = <span class="number">12110586673991788415780355139635579057920926864887110308343229256046868242179445444897790171351302575188607117081580121488253540215781625598048021161675697</span></span><br><span class="line">c1 = <span class="number">14010729418703228234352465883041270611113735889838753433295478495763409056136734155612156934673988344882629541204985909650433819205298939877837314145082403528055884752079219150739849992921393509593620449489882380176216648401057401569934043087087362272303101549800941212057354903559653373299153430753882035233354304783275982332995766778499425529570008008029401325668301144188970480975565215953953985078281395545902102245755862663621187438677596628109967066418993851632543137353041712721919291521767262678140115188735994447949166616101182806820741928292882642234238450207472914232596747755261325098225968268926580993051</span></span><br><span class="line">c2 = <span class="number">14386997138637978860748278986945098648507142864584111124202580365103793165811666987664851210230009375267398957979494066880296418013345006977654742303441030008490816239306394492168516278328851513359596253775965916326353050138738183351643338294802012193721879700283088378587949921991198231956871429805847767716137817313612304833733918657887480468724409753522369325138502059408241232155633806496752350562284794715321835226991147547651155287812485862794935695241612676255374480132722940682140395725089329445356434489384831036205387293760789976615210310436732813848937666608611803196199865435145094486231635966885932646519</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">q = math.gcd(N, <span class="built_in">pow</span>(c1, e2, N) * <span class="built_in">pow</span>(<span class="number">5</span>, e1 * e2, N) - <span class="built_in">pow</span>(c2, e1, N) * <span class="built_in">pow</span>(<span class="number">2</span>, e1 * e2, N))</span><br><span class="line">p = N // q</span><br><span class="line"><span class="built_in">print</span>(p)</span><br><span class="line"><span class="built_in">print</span>(q)</span><br></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;第二章也做完咯~&lt;/p&gt;
    
    </summary>
    
      <category term="学习" scheme="http://smilin9.com/categories/%E5%AD%A6%E4%B9%A0/"/>
    
    
      <category term="cryptohack" scheme="http://smilin9.com/tags/cryptohack/"/>
    
  </entry>
  
  <entry>
    <title>Introduction To Cryptohack</title>
    <link href="http://smilin9.com/2022/05/01/Introduction%20To%20Cryptohack/"/>
    <id>http://smilin9.com/2022/05/01/Introduction To Cryptohack/</id>
    <published>2022-05-01T11:33:32.000Z</published>
    <updated>2022-12-12T14:57:53.173Z</updated>
    
    <content type="html"><![CDATA[<p>做完第一章咯~</p><span id="more"></span><p>做了大半天才做完，主要是 python 语法什么的写起来比较手生，有 python 基础的话可能会做得更顺手一点。</p><p>这一章的知识都属于比较基础的，甚至大部分题几乎都是直接把 flag 怼脸上（笑</p><p>做完题之后犹豫了一下博客是单纯写解题相关还是顺便附上知识点总结，想起之前说的浅（shen）浅（shen）记录，所以还是打算都写写，不是什么坏事捏。</p><h2 id="Finding-Flags"><a href="#Finding-Flags" class="headerlink" title="Finding Flags"></a>Finding Flags</h2><h3 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h3><p>Each challenge is designed to help introduce you to a new piece of cryptography. Solving a challenge will require you to find a “flag”.</p><p>These flags will usually be in the format<code>crypto&#123;y0ur_f1rst_fl4g&#125;</code>. The flag format helps you verify that you found the correct solution.</p><p>Try submitting this into the form below to solve your first challenge.</p><h3 id="Analyze"><a href="#Analyze" class="headerlink" title="Analyze"></a>Analyze</h3><p>简单说了下 flag 是啥，格式是 <code>crypto&#123;y0ur_f1rst_fl4g&#125;</code>。flag 已经给咯，直接填~</p><h2 id="Great-Snakes"><a href="#Great-Snakes" class="headerlink" title="Great Snakes"></a>Great Snakes</h2><h3 id="Description-1"><a href="#Description-1" class="headerlink" title="Description"></a>Description</h3><p>Modern cryptography involves code, and code involves coding. CryptoHack provides a good opportunity to sharpen your skills.</p><p>Of all modern programming languages, Python 3 stands out as ideal for quickly writing cryptographic scripts and attacks.</p><p>Run the attached Python script and it will output your flag.</p><h3 id="Analyze-1"><a href="#Analyze-1" class="headerlink" title="Analyze"></a>Analyze</h3><p>就直接在 python3 下运行 .py 文件就看到 <code>flag</code> 咯。</p><p>直接在 vscode 里跑的时候老是报错，发现第一行注释 <code>#!/usr/bin/env python3</code> 是给 Linux/macOS 环境准备的，Windows 直接删掉就好咯。</p><p><del>（孤儿 Windows 实锤）</del></p><h2 id="ASCII"><a href="#ASCII" class="headerlink" title="ASCII"></a>ASCII</h2><h3 id="Description-2"><a href="#Description-2" class="headerlink" title="Description"></a>Description</h3><p>ASCII is a 7-bit encoding standard which allows the representation of text using the integers 0-127.</p><p>Using the below integer array, convert the numbers to their corresponding ASCII characters to obtain a flag.</p><figure class="highlight accesslog"><table><tr><td class="code"><pre><span class="line"><span class="string">[99, 114, 121, 112, 116, 111, 123, 65, 83, 67, 73, 73, 95, 112, 114, 49, 110, 116, 52, 98, 108, 51, 125]</span></span><br></pre></td></tr></table></figure><blockquote><p>In Python, the <code>chr()</code> function can be used to convert an ASCII ordinal number to a character (the <code>ord()</code> function does the opposite).</p></blockquote><h3 id="Analyze-2"><a href="#Analyze-2" class="headerlink" title="Analyze"></a>Analyze</h3><p>介绍了下 ASCII 是啥，直接按给出的 <code>chr()</code> 函数转换一下输出 <code>flag</code>。</p><h3 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="built_in">ord</span> = [<span class="number">99</span>, <span class="number">114</span>, <span class="number">121</span>, <span class="number">112</span>, <span class="number">116</span>, <span class="number">111</span>, <span class="number">123</span>, <span class="number">65</span>, <span class="number">83</span>, <span class="number">67</span>, <span class="number">73</span>, <span class="number">73</span>, <span class="number">95</span>, <span class="number">112</span>, <span class="number">114</span>, <span class="number">49</span>, <span class="number">110</span>, <span class="number">116</span>,</span><br><span class="line">       <span class="number">52</span>, <span class="number">98</span>, <span class="number">108</span>, <span class="number">51</span>, <span class="number">125</span>]</span><br><span class="line"></span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;&#x27;</span>.join(<span class="built_in">chr</span>(o) <span class="keyword">for</span> o <span class="keyword">in</span> <span class="built_in">ord</span>))</span><br></pre></td></tr></table></figure><h3 id="SumUp"><a href="#SumUp" class="headerlink" title="SumUp"></a>SumUp</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">function:</span><br><span class="line"><span class="built_in">chr</span>()  <span class="comment"># ASCII--&gt;char</span></span><br><span class="line"><span class="built_in">ord</span>()  <span class="comment"># char--&gt;ASCII</span></span><br></pre></td></tr></table></figure><h2 id="Hex"><a href="#Hex" class="headerlink" title="Hex"></a>Hex</h2><h3 id="Description-3"><a href="#Description-3" class="headerlink" title="Description"></a>Description</h3><p>When we encrypt something the resulting ciphertext commonly has bytes which are not printable ASCII characters. If we want to share our encrypted data, it’s common to encode it into something more user-friendly and portable across different systems.</p><p>Included below is a flag encoded as a hex string. Decode this back into bytes to get the flag.</p><figure class="highlight llvm"><table><tr><td class="code"><pre><span class="line"><span class="number">63727970746</span>f<span class="number">7</span>b<span class="number">596</span>f<span class="number">755</span>f<span class="number">77696</span><span class="keyword">c</span><span class="number">6</span><span class="keyword">c</span><span class="number">5</span>f<span class="number">62655</span>f<span class="number">776</span>f<span class="number">726</span>b<span class="number">696e675</span>f<span class="number">776974685</span>f<span class="number">6865785</span>f<span class="number">737472696e67735</span>f<span class="number">615</span>f<span class="number">6</span><span class="keyword">c</span><span class="number">6</span>f<span class="number">747</span>d</span><br></pre></td></tr></table></figure><p> In Python, the <code>bytes.fromhex()</code> function can be used to convert hex to bytes. The <code>.hex()</code> instance method can be called on byte strings to get the hex representation.</p><h3 id="Analyze-3"><a href="#Analyze-3" class="headerlink" title="Analyze"></a>Analyze</h3><p>十六进制来咯。</p><p>要求把给出的十六进制 decode 回 byte，用给出的函数直接 decode 输出。</p><h3 id="Code-1"><a href="#Code-1" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">h = <span class="string">&#x27;63727970746f7b596f755f77696c6c5f62655f776f726b696e675f77697685f6865785f737472696e67\</span></span><br><span class="line"><span class="string">35f615f6c6f747d&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(<span class="built_in">bytes</span>.fromhex(h))</span><br></pre></td></tr></table></figure><h3 id="SumUp-1"><a href="#SumUp-1" class="headerlink" title="SumUp"></a>SumUp</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line">function:</span><br><span class="line"><span class="built_in">bytes</span>.fromhex()  <span class="comment"># hex--&gt;bytes</span></span><br><span class="line"><span class="built_in">bytes</span>.<span class="built_in">hex</span>()  <span class="comment"># bytes--&gt;hex</span></span><br></pre></td></tr></table></figure><h2 id="Base64"><a href="#Base64" class="headerlink" title="Base64"></a>Base64</h2><h3 id="Description-4"><a href="#Description-4" class="headerlink" title="Description"></a>Description</h3><p>Another common encoding scheme is Base64, which allows us to represent binary data as an ASCII string using 64 characters. One character of a Base64 string encodes 6 bits, and so 4 characters of Base64 encode three 8-bit bytes.</p><p>Base64 is most commonly used online, so binary data such as images can be easily included into HTML or CSS files.</p><p>Take the below hex string, <em>decode</em> it into bytes and then <em>encode</em> it into Base64.</p><figure class="highlight"><table><tr><td class="code"><pre><span class="line">72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf</span><br></pre></td></tr></table></figure><p> In Python, after importing the base64 module with <code>import base64</code>, you can use the <code>base64.b64encode()</code> function. Remember to decode the hex first as the challenge description states.</p><h3 id="Analyze-4"><a href="#Analyze-4" class="headerlink" title="Analyze"></a>Analyze</h3><p>是 base64 捏，给的是十六进制字符串，先用 <code>bytes.fromhex</code> 函数 encode 得到 byte，然后用 base64 库里的 <code>base64.b64encode()</code> 函数编码。</p><p>记得先安 base64 库喔~</p><h3 id="Code-2"><a href="#Code-2" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> base64</span><br><span class="line"></span><br><span class="line">h = <span class="string">&#x27;72bca9b68fc16ac7beeb8f849dca1d8a783e8acf9679bf9269f7bf&#x27;</span></span><br><span class="line">decode = <span class="built_in">bytes</span>.fromhex(h)  <span class="comment"># hex --&gt; bytes</span></span><br><span class="line"><span class="built_in">print</span>(base64.b64encode(decode))  <span class="comment"># base64 编码</span></span><br></pre></td></tr></table></figure><h3 id="SumUp-2"><a href="#SumUp-2" class="headerlink" title="SumUp"></a>SumUp</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> base64</span><br><span class="line">base64.b64encode() <span class="comment"># bytes--&gt;base64Code</span></span><br></pre></td></tr></table></figure><h2 id="Bytes-and-Big-Integers"><a href="#Bytes-and-Big-Integers" class="headerlink" title="Bytes and Big Integers"></a>Bytes and Big Integers</h2><h3 id="Description-5"><a href="#Description-5" class="headerlink" title="Description"></a>Description</h3><p>Cryptosystems like RSA works on numbers, but messages are made up of characters. How should we convert our messages into numbers so that mathematical operations can be applied?</p><p>The most common way is to take the ordinal bytes of the message, convert them into hexadecimal, and concatenate. This can be interpreted as a base-16 number, and also represented in base-10.</p><p>To illustrate:</p><figure class="highlight apache"><table><tr><td class="code"><pre><span class="line"><span class="attribute">message</span>: HELLO</span><br><span class="line"><span class="attribute">ascii</span> bytes:<span class="meta"> [72, 69, 76, 76, 79]</span></span><br><span class="line"><span class="attribute">hex</span> bytes:<span class="meta"> [0x48, 0x45, 0x4c, 0x4c, 0x4f]</span></span><br><span class="line"><span class="attribute">base</span>-<span class="number">16</span>: <span class="number">0</span>x48454c4c4f</span><br><span class="line"><span class="attribute">base</span>-<span class="number">10</span>: <span class="number">310400273487</span></span><br></pre></td></tr></table></figure><blockquote><p>Python’s PyCryptodome library implements this with the methods <code>Crypto.Util.number.bytes_to_long()</code> and <code>Crypto.Util.number.long_to_bytes()</code>. You may first have to install PyCryptodome and import it with <code>from Crypto.Util.number import *</code>. </p></blockquote><p>Convert the following integer back into a message:</p><figure class="highlight"><table><tr><td class="code"><pre><span class="line">11515195063862318899931685488813747395775516287289682636499965282714637259206269</span><br></pre></td></tr></table></figure><h3 id="Analyze-5"><a href="#Analyze-5" class="headerlink" title="Analyze"></a>Analyze</h3><p>给了一个大整数，用函数 <code>long_to_bytes()</code> 转化下就解决咯。</p><h3 id="Code-3"><a href="#Code-3" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto.Util.number <span class="keyword">import</span> *</span><br><span class="line"></span><br><span class="line">lis = <span class="number">11515195063862318899931685488813747395775516287289682636499965282714637259206269</span></span><br><span class="line"><span class="built_in">print</span>(long_to_bytes(lis))</span><br></pre></td></tr></table></figure><h3 id="SumUp-3"><a href="#SumUp-3" class="headerlink" title="SumUp"></a>SumUp</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> Crypto.Util.number <span class="keyword">import</span> *</span><br><span class="line">Crypto.Util.number.bytes_to_long()</span><br><span class="line">Crypto.Util.number.long_to_bytes()</span><br></pre></td></tr></table></figure><p>虽然但是，我一定要吐槽 Crypto 库，这也太烦了！</p><p>安了之后还是不停报错说没有找到 Crypto 库，又是卸载重装又是重启。</p><p>试了一系列办法之后求助互联网，去 <code>.\python310\Lib\site-packages</code> 里面把 crypto 文件夹直接重命名为 Crypto，然后它就好了？代码就跑起来了！</p><p>装 py 库真的可以治疗低血压。。</p><h2 id="XOR-Starter"><a href="#XOR-Starter" class="headerlink" title="XOR Starter"></a>XOR Starter</h2><h3 id="Description-6"><a href="#Description-6" class="headerlink" title="Description"></a>Description</h3><p>XOR is a bitwise operator which returns 0 if the bits are the same, and 1 otherwise. In textbooks the XOR operator is denoted by ⊕, but in most challenges and programming languages you will see the caret <code>^</code> used instead.</p><div class="table-container"><table><thead><tr><th style="text-align:center">A</th><th style="text-align:center">B</th><th style="text-align:center">Output</th></tr></thead><tbody><tr><td style="text-align:center">0</td><td style="text-align:center">0</td><td style="text-align:center">0</td></tr><tr><td style="text-align:center">0</td><td style="text-align:center">1</td><td style="text-align:center">1</td></tr><tr><td style="text-align:center">1</td><td style="text-align:center">0</td><td style="text-align:center">1</td></tr><tr><td style="text-align:center">1</td><td style="text-align:center">1</td><td style="text-align:center">0</td></tr></tbody></table></div><p>For longer binary numbers we XOR bit by bit: <code>0110 ^ 1010 = 1100</code>. We can XOR integers by first converting the integer from decimal to binary. We can XOR strings by first converting each character to the integer representing the Unicode character.</p><p>Given the string <code>&quot;label&quot;</code>, XOR each character with the integer <code>13</code>. Convert these integers back to a string and submit the flag as <code>crypto&#123;new_string&#125;</code>.</p><blockquote><p>The Python <code>pwntools</code> library has a convenient <code>xor()</code> function that can XOR together data of different types and lengths.</p></blockquote><h3 id="Analyze-6"><a href="#Analyze-6" class="headerlink" title="Analyze"></a>Analyze</h3><p>给了字符串 <code>&quot;label&quot;</code>，每个字符和整数 13 异或得到 flag。</p><p>顺手下载 pwntools 和 pwn 库喔~</p><p><code>pip install pwntools</code></p><p><code>pip install pwn</code></p><h3 id="Code-4"><a href="#Code-4" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">XOR</span>(<span class="params"><span class="built_in">str</span>, key</span>):</span><br><span class="line">    res=<span class="string">&#x27;&#x27;</span></span><br><span class="line">    <span class="keyword">for</span> s <span class="keyword">in</span> <span class="built_in">str</span>:</span><br><span class="line">        res += <span class="built_in">chr</span>(<span class="built_in">ord</span>(s) ^ key)</span><br><span class="line">    <span class="comment">#print(o)</span></span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line"></span><br><span class="line"><span class="built_in">str</span> = <span class="string">&#x27;label&#x27;</span></span><br><span class="line">flag = XOR(<span class="built_in">str</span>,<span class="number">13</span>)</span><br><span class="line"><span class="built_in">print</span>(<span class="string">&#x27;crypto&#123;%s&#125;&#x27;</span>% flag)</span><br></pre></td></tr></table></figure><h3 id="SumUp-4"><a href="#SumUp-4" class="headerlink" title="SumUp"></a>SumUp</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> pwntools <span class="keyword">import</span> xor</span><br><span class="line">xor()  <span class="comment"># 可以把不同长度和类型的数据进行异或，什么类型的数据都可以喔</span></span><br></pre></td></tr></table></figure><h2 id="XOR-Properties"><a href="#XOR-Properties" class="headerlink" title="XOR Properties"></a>XOR Properties</h2><h3 id="Description-7"><a href="#Description-7" class="headerlink" title="Description"></a>Description</h3><p>In the last challenge, you saw how XOR worked at the level of bits. In this one, we’re going to cover the properties of the XOR operation and then use them to undo a chain of operations that have encrypted a flag. Gaining an intuition for how this works will help greatly when you come to attacking real cryptosystems later, especially in the block ciphers category.</p><p>There are four main properties we should consider when we solve challenges using the XOR operator</p><figure class="highlight dns"><table><tr><td class="code"><pre><span class="line">Commutative: <span class="keyword">A</span> ⊕ B = B ⊕ <span class="keyword">A</span></span><br><span class="line">Associative: <span class="keyword">A</span> ⊕ (B ⊕ C) = (<span class="keyword">A</span> ⊕ B) ⊕ C</span><br><span class="line">Identity: <span class="keyword">A</span> ⊕ <span class="number">0</span> = <span class="keyword">A</span></span><br><span class="line">Self-Inverse: <span class="keyword">A</span> ⊕ <span class="keyword">A</span> = <span class="number">0</span></span><br></pre></td></tr></table></figure><p>Let’s break this down. Commutative means that the order of the XOR operations is not important. Associative means that a chain of operations can be carried out without order (we do not need to worry about brackets). The identity is 0, so XOR with 0 “does nothing”, and lastly something XOR’d with itself returns zero.</p><p>Let’s try this out in action! Below is a series of outputs where three random keys have been XOR’d together and with the flag. Use the above properties to undo the encryption in the final line to obtain the flag.</p><figure class="highlight llvm"><table><tr><td class="code"><pre><span class="line">KEY<span class="number">1</span> <span class="operator">=</span> a<span class="number">6</span><span class="keyword">c</span><span class="number">8</span>b<span class="number">6733</span><span class="keyword">c</span><span class="number">9</span>b<span class="number">22</span>de<span class="number">7</span>bc<span class="number">0253266</span>a<span class="number">3867</span>df<span class="number">55</span>acde<span class="number">8635e19</span><span class="keyword">c</span><span class="number">73313</span></span><br><span class="line">KEY<span class="number">2</span> ^ KEY<span class="number">1</span> <span class="operator">=</span> <span class="number">37</span>dcb<span class="number">292030</span>faa<span class="number">90</span>d<span class="number">07</span>eec<span class="number">17e3</span>b<span class="number">1</span><span class="keyword">c</span><span class="number">6</span>d<span class="number">8</span>daf<span class="number">94</span><span class="keyword">c</span><span class="number">35</span>d<span class="number">4</span><span class="keyword">c</span><span class="number">9191</span>a<span class="number">5e1</span>e</span><br><span class="line">KEY<span class="number">2</span> ^ KEY<span class="number">3</span> <span class="operator">=</span> <span class="keyword">c</span><span class="number">1545756687e7573</span>db<span class="number">23</span>aa<span class="number">1</span><span class="keyword">c</span><span class="number">3452</span>a<span class="number">098</span>b<span class="number">71</span>a<span class="number">7</span>fbf<span class="number">0</span>fddddde<span class="number">5</span>fc<span class="number">1</span></span><br><span class="line">FLAG ^ KEY<span class="number">1</span> ^ KEY<span class="number">3</span> ^ KEY<span class="number">2</span> <span class="operator">=</span> <span class="number">04</span>ee<span class="number">9855208</span>a<span class="number">2</span>cd<span class="number">59091</span>d<span class="number">04767</span>ae<span class="number">47963170</span>d<span class="number">1660</span>df<span class="number">7</span>f<span class="number">56</span>f<span class="number">5</span>faf</span><br></pre></td></tr></table></figure><p> Before you XOR these objects, be sure to decode from hex to bytes.</p><h3 id="Analyze-7"><a href="#Analyze-7" class="headerlink" title="Analyze"></a>Analyze</h3><p>异或的一些性质~</p><p>很简单的一点数学运算</p><script type="math/tex; mode=display">\begin{align}&FK123⊕K1⊕K23 \\\ =&(F⊕K1⊕K2⊕K3)⊕K1⊕(K2⊕K3) \\\ =&(F⊕K2⊕K3)⊕0⊕(K2⊕K3) \\\ =&(F⊕K2⊕K3)⊕(K2⊕K3) \\\ =&F⊕0 \\\ =&F\end{align}</script><p>（其实只是想浅试一下数学公式的功能~</p><h3 id="Code-5"><a href="#Code-5" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> xor</span><br><span class="line">K1 = <span class="string">&#x27;a6c8b6733c9b22de7bc0253266a3867df55acde8635e19c73313&#x27;</span></span><br><span class="line">K21 = <span class="string">&#x27;37dcb292030faa90d07eec17e3b1c6d8daf94c35d4c9191a5e1e&#x27;</span></span><br><span class="line">K23 = <span class="string">&#x27;c1545756687e7573db23aa1c3452a098b71a7fbf0fddddde5fc1&#x27;</span></span><br><span class="line">FK132 = <span class="string">&#x27;04ee9855208a2cd59091d04767ae47963170d1660df7f56f5faf&#x27;</span></span><br><span class="line">flag = xor(<span class="built_in">bytes</span>.fromhex(FK132), <span class="built_in">bytes</span>.fromhex(K1), <span class="built_in">bytes</span>.fromhex(K23))</span><br><span class="line"><span class="built_in">print</span>(flag)</span><br></pre></td></tr></table></figure><h2 id="Favourite-byte"><a href="#Favourite-byte" class="headerlink" title="Favourite byte"></a>Favourite byte</h2><h3 id="Description-8"><a href="#Description-8" class="headerlink" title="Description"></a>Description</h3><p>For the next few challenges, you’ll use what you’ve just learned to solve some more XOR puzzles.</p><p>I’ve hidden some data using XOR with a single byte, but that byte is a secret. Don’t forget to decode from hex first.</p><figure class="highlight"><table><tr><td class="code"><pre><span class="line">73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d</span><br></pre></td></tr></table></figure><h3 id="Analyze-8"><a href="#Analyze-8" class="headerlink" title="Analyze"></a>Analyze</h3><p>先从16进制 decode 喔</p><p>因为之和单个 byte 进行了异或，又知道 flag 的首字母是 <code>&#39;c&#39;</code>，所以可以用 decode 之后的第一位和 <code>&#39;c&#39;</code> 进行异或得到 secret。</p><p>之后把整个字符串和 secret 异或之后输出。</p><h3 id="Code-6"><a href="#Code-6" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">def</span> <span class="title function_">xor_byte</span>(<span class="params">a: <span class="built_in">bytes</span>, b: <span class="built_in">int</span></span>):</span><br><span class="line">    res = <span class="built_in">bytes</span>([_a ^ b <span class="keyword">for</span> _a <span class="keyword">in</span> a])</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line"></span><br><span class="line">lis = <span class="string">&#x27;73626960647f6b206821204f21254f7d694f7624662065622127234f726927756d&#x27;</span></span><br><span class="line">decode = <span class="built_in">bytes</span>.fromhex(lis)</span><br><span class="line">secret = decode[<span class="number">0</span>] ^ <span class="built_in">ord</span>(<span class="string">&#x27;c&#x27;</span>)</span><br><span class="line"><span class="built_in">print</span>(xor_byte(decode, secret))</span><br></pre></td></tr></table></figure><h2 id="You-either-know-XOR-you-don’t"><a href="#You-either-know-XOR-you-don’t" class="headerlink" title="You either know, XOR you don’t"></a>You either know, XOR you don’t</h2><h3 id="Description-9"><a href="#Description-9" class="headerlink" title="Description"></a>Description</h3><p>I’ve encrypted the flag with my secret key, you’ll never be able to guess it.</p><blockquote><p>Remember the flag format and how it might help you in this challenge!</p></blockquote><figure class="highlight dns"><table><tr><td class="code"><pre><span class="line"><span class="number">0</span>e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e<span class="number">263451150104</span></span><br></pre></td></tr></table></figure><h3 id="Analyze-9"><a href="#Analyze-9" class="headerlink" title="Analyze"></a>Analyze</h3><p>第一步当然也是从十六进制 decode 咯。</p><p>和上一题的思路有点像捏，也可以利用 flag 的格式得到加密用到的 key。</p><p>只要把 <code>&#39;c&#39;</code> 换成 <code>&#39;crypto&#123;&#39;</code>，然后加上一点点的猜想<del>（自动补全）</del>就可以咯。</p><h3 id="Code-7"><a href="#Code-7" class="headerlink" title="Code"></a>Code</h3><figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> xor</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">lis = <span class="string">&#x27;0e0b213f26041e480b26217f27342e175d0e070a3c5b103e2526217f27342e175d0e077e263451150\</span></span><br><span class="line"><span class="string">104&#x27;</span></span><br><span class="line">decode = <span class="built_in">bytes</span>.fromhex(lis)</span><br><span class="line">flag = <span class="string">&#x27;crypto&#123;&#x27;</span></span><br><span class="line"><span class="comment"># akey = xor(decode[:7], [ord(o) for o in flag])</span></span><br><span class="line"><span class="comment"># print(akey)</span></span><br><span class="line">key = <span class="string">&#x27;myXORkey&#x27;</span></span><br><span class="line"><span class="built_in">print</span>(xor(decode, key))</span><br><span class="line"></span><br><span class="line"><span class="comment"># akey = myXORke,猜想key = myXORkey</span></span><br></pre></td></tr></table></figure><h2 id="致谢（被迫的）"><a href="#致谢（被迫的）" class="headerlink" title="致谢（被迫的）"></a>致谢<del>（被迫的）</del></h2><p>非常感谢 <a href="https://hawa130.com/">hawa130</a> 对本文排版等问题的细心纠正。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;做完第一章咯~&lt;/p&gt;
    
    </summary>
    
      <category term="学习" scheme="http://smilin9.com/categories/%E5%AD%A6%E4%B9%A0/"/>
    
    
      <category term="cryptohack" scheme="http://smilin9.com/tags/cryptohack/"/>
    
  </entry>
  
  <entry>
    <title>Start Of Cryptohack</title>
    <link href="http://smilin9.com/2022/04/30/start%20of%20cryptohack/"/>
    <id>http://smilin9.com/2022/04/30/start of cryptohack/</id>
    <published>2022-04-30T20:04:32.000Z</published>
    <updated>2022-12-12T14:57:53.177Z</updated>
    
    <content type="html"><![CDATA[<p>刚刚搭好博客，来水第一篇文章咯！（bushi</p><span id="more"></span><p>今天去面试 xdsec 咯，虽然很紧张也磕磕绊绊，但总算是结束咯。只是最后惊闻噩耗，面试任务 5.7 截止，所以整个五一假期都要用来做面试任务，那我当然心甘情愿 <del>很不乐意</del> 。又因为想要快点充实自己的博客然后拿去和朋友们分享，所以想到可以用这个博客浅（shen）浅（shen）记录一下学习过程。（和解题思路？虽然面试师傅说布置的都是简单基础题，但是可能对小白 <del>指我</del> 来说还是需要一些思考的吧</p><p>说到这个，想起去年鸽掉了二面，当时虽然想进协会但是自己是个懒狗<del>（可能现在也是）</del>，后来面试师傅刚好是好朋友，一直在催我学相关知识，也很感谢师傅的操心（bushi），如果只是自己一个人的话，很可能就不会再去试着学习这方面的东西提升自己了。</p><p>不管结果怎么样，就是说希望自己这次可以好好学几天东西，算是给自己一个交代吧。</p><p>对咯，接下来 tag:cryptohack 底下的文章都会是 <a href="https://cryptohack.org/">cryptohack</a> 上的题，如果你也是和我一样的小白，也许可以通过这些文章和我一起学习喔。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;刚刚搭好博客，来水第一篇文章咯！（bushi&lt;/p&gt;
    
    </summary>
    
      <category term="学习" scheme="http://smilin9.com/categories/%E5%AD%A6%E4%B9%A0/"/>
    
    
      <category term="cryptohack" scheme="http://smilin9.com/tags/cryptohack/"/>
    
      <category term="垃圾桶" scheme="http://smilin9.com/tags/%E5%9E%83%E5%9C%BE%E6%A1%B6/"/>
    
  </entry>
  
  <entry>
    <title>Hello World！</title>
    <link href="http://smilin9.com/2022/04/30/hello-world/"/>
    <id>http://smilin9.com/2022/04/30/hello-world/</id>
    <published>2022-04-30T07:30:00.000Z</published>
    <updated>2022-12-12T14:57:53.177Z</updated>
    
    <content type="html"><![CDATA[<p>欢迎来到飞飞鱼的 Blog！这是本博客的第一篇文章。</p><span id="more"></span><p>这是<del>超厉害的</del> smilin9 历时两天（其实加起来不到一天）搭建的静态博客。</p><p>非常感谢 <a href="https://hawa130.com/">hawa130</a> 耐心解答我的一系列傻瓜问题。</p><p>欢迎交流学习！</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;欢迎来到飞飞鱼的 Blog！这是本博客的第一篇文章。&lt;/p&gt;
    
    </summary>
    
    
      <category term="垃圾桶" scheme="http://smilin9.com/tags/%E5%9E%83%E5%9C%BE%E6%A1%B6/"/>
    
  </entry>
  
</feed>
