<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>Hash - tag - 沐木</title><link>https://oldletter.cn/tags/hash/</link><description>Hash - tag - 沐木</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Fri, 10 Feb 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://oldletter.cn/tags/hash/" rel="self" type="application/rss+xml"/><item><title>密码学基础：Hash、对称加密、非对称加密</title><link>https://oldletter.cn/posts/crypto-01-fundamentals/</link><pubDate>Thu, 05 Jan 2023 00:00:00 +0000</pubDate><author>mumu</author><guid>https://oldletter.cn/posts/crypto-01-fundamentals/</guid><description><![CDATA[<blockquote>
<p>作者：林 | 系列：密码学 | 适合读者：后端开发 / 对密码学感兴趣的工程师</p></blockquote>
<hr>
<h2 id="一为什么要懂密码学">一、为什么要懂密码学</h2>
<p>作为开发者，你可能每天都在用密码学而不自知：</p>
<ul>
<li>HTTPS 连接 → TLS 握手（非对称 + 对称加密）</li>
<li>用户密码存储 → BCrypt/Argon2（散列函数）</li>
<li>JWT Token → HMAC-SHA256（消息认证码）</li>
<li>支付接口签名 → RSA/SM2（数字签名）</li>
<li>数据库敏感字段 → AES/SM4（对称加密）</li>
</ul>
<p>密码学并非安全团队的专属，重点是每个后端工程师的基本功。本文用下限的篇幅把三大支柱讲清楚，后续每篇深入一个方向。</p>
<hr>
<h2 id="二三大分类总览">二、三大分类总览</h2>
<table>
  <thead>
      <tr>
          <th>能力</th>
          <th>散列函数</th>
          <th>对称密码</th>
          <th>公钥密码</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>主要用途</td>
          <td>完整性、派生、消息认证的组成部分</td>
          <td>数据机密性与认证加密</td>
          <td>密钥协商、签名，部分算法支持加密</td>
      </tr>
      <tr>
          <td>是否可逆</td>
          <td>不可逆</td>
          <td>持有密钥可解密</td>
          <td>取决于具体算法与用途</td>
      </tr>
      <tr>
          <td>密钥</td>
          <td>普通散列无密钥，HMAC 有密钥</td>
          <td>双方共享密钥</td>
          <td>公钥与私钥成对</td>
      </tr>
      <tr>
          <td>常见算法</td>
          <td>SHA-2、SHA-3、SM3</td>
          <td>AES、SM4、ChaCha20</td>
          <td>RSA、ECC、SM2</td>
      </tr>
  </tbody>
</table>
<p>核心区别一句话：</p>
<ul>
<li><strong>Hash</strong>：单向压缩，不能解密，用于验证完整性</li>
<li><strong>对称加密</strong>：一把钥匙，能加能解，用于加密数据</li>
<li><strong>非对称加密</strong>：两把钥匙，公私配对，用于密钥交换和签名</li>
</ul>
<hr>
<h2 id="三散列函数hash">三、散列函数（Hash）</h2>
<h3 id="31-特征">3.1 特征</h3>
<table>
  <thead>
      <tr>
          <th>特征</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>单向性</td>
          <td>从哈希值无法反推出原文</td>
      </tr>
      <tr>
          <td>固定长度</td>
          <td>无论输入多长，输出长度固定</td>
      </tr>
      <tr>
          <td>雪崩效应</td>
          <td>输入改一个 bit，输出变化超过 50%</td>
      </tr>
      <tr>
          <td>抗碰撞</td>
          <td>找到两个不同输入产生相同输出，计算上不可行</td>
      </tr>
  </tbody>
</table>
<h3 id="32-常见算法">3.2 常见算法</h3>
<table>
  <thead>
      <tr>
          <th>算法</th>
          <th>输出长度</th>
          <th>状态</th>
          <th>用途</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>MD5</td>
          <td>128 bit</td>
          <td>❌ 已破解</td>
          <td>仅用于文件校验（非安全场景）</td>
      </tr>
      <tr>
          <td>SHA-1</td>
          <td>160 bit</td>
          <td>❌ 已破解</td>
          <td>不应再使用</td>
      </tr>
      <tr>
          <td>SHA-256</td>
          <td>256 bit</td>
          <td>✅ 安全</td>
          <td>数字签名、证书、区块链</td>
      </tr>
      <tr>
          <td>SHA-3</td>
          <td>可变</td>
          <td>✅ 安全</td>
          <td>SHA-2 的备选方案</td>
      </tr>
      <tr>
          <td>SM3</td>
          <td>256 bit</td>
          <td>✅ 安全</td>
          <td>国密体系，对标 SHA-256</td>
      </tr>
  </tbody>
</table>
<h3 id="33-代码示例">3.3 代码示例</h3>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-java">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title=""><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="kn">import</span><span class="w"> </span><span class="nn">java.security.MessageDigest</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// SHA-256</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kt">byte</span><span class="o">[]</span><span class="w"> </span><span class="n">hash</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">MessageDigest</span><span class="p">.</span><span class="na">getInstance</span><span class="p">(</span><span class="s">&#34;SHA-256&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">.</span><span class="na">digest</span><span class="p">(</span><span class="s">&#34;hello&#34;</span><span class="p">.</span><span class="na">getBytes</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// SM3（需要 BouncyCastle）</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kt">byte</span><span class="o">[]</span><span class="w"> </span><span class="n">sm3Hash</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">MessageDigest</span><span class="p">.</span><span class="na">getInstance</span><span class="p">(</span><span class="s">&#34;SM3&#34;</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">.</span><span class="na">digest</span><span class="p">(</span><span class="s">&#34;hello&#34;</span><span class="p">.</span><span class="na">getBytes</span><span class="p">());</span></span></span></code></pre></div></div>
<h3 id="34-典型应用">3.4 典型应用</h3>
<table>
  <thead>
      <tr>
          <th>场景</th>
          <th>做法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>密码存储</td>
          <td>BCrypt/Argon2（带盐的慢哈希）</td>
      </tr>
      <tr>
          <td>文件完整性校验</td>
          <td>SHA-256 摘要比对</td>
      </tr>
      <tr>
          <td>消息认证（HMAC）</td>
          <td>HMAC-SHA256(key, message)</td>
      </tr>
      <tr>
          <td>数字签名</td>
          <td>先 Hash 再用私钥签 Hash 值</td>
      </tr>
      <tr>
          <td>区块链</td>
          <td>SHA-256 链式哈希</td>
      </tr>
  </tbody>
</table>
<div class="details admonition warning open">
    <div class="details-summary admonition-title">
        <i class="icon fas fa-exclamation" aria-hidden="true"></i>别用 MD5/SHA-1 做安全用途<i class="details-icon fas fa-angle-right" aria-hidden="true"></i>
    </div>
    <div class="details-content">
        <div class="admonition-content">MD5 碰撞攻击成本已低至几秒，SHA-1 也在 2017 年被 Google 实际碰撞。密码存储、签名验证等安全场景，必须用 SHA-256+ 或 SM3。</div>
    </div>
</div>
<hr>
<h2 id="四对称加密symmetric-encryption">四、对称加密（Symmetric Encryption）</h2>
<h3 id="41-原理">4.1 原理</h3>
<p>加密和解密使用<strong>同一把密钥</strong>：</p>]]></description></item><item><title>散列函数：MD5、SHA、SM3 与 HMAC</title><link>https://oldletter.cn/posts/crypto-02-hash/</link><pubDate>Fri, 10 Feb 2023 00:00:00 +0000</pubDate><author>mumu</author><guid>https://oldletter.cn/posts/crypto-02-hash/</guid><description><![CDATA[<blockquote>
<p>作者：林 | 系列：密码学 | 适合读者：后端开发 / 安全工程师</p></blockquote>
<hr>
<h2 id="一什么是散列函数">一、什么是散列函数</h2>
<p>散列函数（Hash Function）将任意长度的输入映射为固定长度的输出，且这个过程<strong>不可逆</strong>。</p>
<div class="code-block code-line-numbers open" style="counter-reset: code-block 0">
    <div class="code-header language-text">
        <span class="code-title"><i class="arrow fas fa-angle-right" aria-hidden="true"></i></span>
        <span class="ellipses"><i class="fas fa-ellipsis-h" aria-hidden="true"></i></span>
        <span class="copy" title=""><i class="far fa-copy" aria-hidden="true"></i></span>
    </div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">输入（任意长度）       →  散列函数  →  输出（固定长度）
</span></span><span class="line"><span class="cl">&#34;hello&#34;              →  SHA-256  →  2cf24dba5fb0a30e...（64 hex = 256 bit）
</span></span><span class="line"><span class="cl">&#34;hello world&#34;        →  SHA-256  →  b94d27b9934d3e08...（64 hex = 256 bit）
</span></span><span class="line"><span class="cl">整本《红楼梦》(2MB)   →  SHA-256  →  固定 64 hex 字符</span></span></code></pre></div></div>
<h3 id="11-密码学安全散列的四个性质">1.1 密码学安全散列的四个性质</h3>
<table>
  <thead>
      <tr>
          <th>性质</th>
          <th>含义</th>
          <th>被破坏的后果</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>单向性</strong>（Preimage Resistance）</td>
          <td>给定 h，找不到 m 使得 H(m)=h</td>
          <td>能从哈希值反推出原文</td>
      </tr>
      <tr>
          <td><strong>第二原像抗性</strong>（Second Preimage）</td>
          <td>给定 m1，找不到 m2≠m1 使得 H(m1)=H(m2)</td>
          <td>能伪造替换文件</td>
      </tr>
      <tr>
          <td><strong>抗碰撞性</strong>（Collision Resistance）</td>
          <td>找不到任意 m1≠m2 使得 H(m1)=H(m2)</td>
          <td>能伪造证书/签名</td>
      </tr>
      <tr>
          <td><strong>雪崩效应</strong>（Avalanche Effect）</td>
          <td>输入改 1 bit，输出至少变化 50%</td>
          <td>能通过输出推测输入特征</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="二主流算法对比">二、主流算法对比</h2>
<h3 id="21-算法一览">2.1 算法一览</h3>
<table>
  <thead>
      <tr>
          <th>算法</th>
          <th>输出长度</th>
          <th>分组长度</th>
          <th>结构</th>
          <th>安全状态</th>
          <th>性能（相对）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>MD5</td>
          <td>128 bit</td>
          <td>512 bit</td>
          <td>Merkle-Damgård</td>
          <td>❌ 碰撞已破解</td>
          <td>速度高</td>
      </tr>
      <tr>
          <td>SHA-1</td>
          <td>160 bit</td>
          <td>512 bit</td>
          <td>Merkle-Damgård</td>
          <td>❌ 碰撞已破解</td>
          <td>快</td>
      </tr>
      <tr>
          <td>SHA-256</td>
          <td>256 bit</td>
          <td>512 bit</td>
          <td>Merkle-Damgård</td>
          <td>✅ 安全</td>
          <td>中</td>
      </tr>
      <tr>
          <td>SHA-512</td>
          <td>512 bit</td>
          <td>1024 bit</td>
          <td>Merkle-Damgård</td>
          <td>✅ 安全</td>
          <td>64位机更快</td>
      </tr>
      <tr>
          <td>SHA-3(256)</td>
          <td>256 bit</td>
          <td>1088 bit</td>
          <td>Sponge（海绵结构）</td>
          <td>✅ 安全</td>
          <td>略慢</td>
      </tr>
      <tr>
          <td>SM3</td>
          <td>256 bit</td>
          <td>512 bit</td>
          <td>Merkle-Damgård</td>
          <td>✅ 安全</td>
          <td>与 SHA-256 相当</td>
      </tr>
      <tr>
          <td>BLAKE3</td>
          <td>256 bit</td>
          <td>64 byte</td>
          <td>Merkle Tree</td>
          <td>✅ 安全</td>
          <td>极快（可并行）</td>
      </tr>
  </tbody>
</table>
<h3 id="22-md5为什么不能再用">2.2 MD5：为什么不能再用</h3>
<p>MD5 的碰撞攻击已经非常成熟：</p>]]></description></item></channel></rss>