<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>国密 - tag - 沐木</title><link>https://oldletter.cn/tags/%E5%9B%BD%E5%AF%86/</link><description>国密 - tag - 沐木</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Fri, 10 Oct 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://oldletter.cn/tags/%E5%9B%BD%E5%AF%86/" rel="self" type="application/rss+xml"/><item><title>常用工具类汇总：SM2/SM4/拼音/文件/HTTP 全覆盖</title><link>https://oldletter.cn/posts/java-04-utils/</link><pubDate>Fri, 10 Oct 2025 00:00:00 +0000</pubDate><author>mumu</author><guid>https://oldletter.cn/posts/java-04-utils/</guid><description><![CDATA[<blockquote>
<p>📅 2026-05-15 | 🏷️ Java, 工具类, 国密, Hutool | 📖 阅读约 18 分钟</p></blockquote>
<h2 id="一背景">一、背景</h2>
<p>多年项目中积累了不少高频使用的工具代码。它们不算复杂，但每次要用的时候都得翻老项目找，效率很低。这篇文章把它们整理出来，统一收录，方便查阅和复用。</p>
<p>每个工具都包含：<strong>使用场景 → 完整代码 → 调用示例</strong>。</p>
<div class="details admonition tip open">
    <div class="details-summary admonition-title">
        <i class="icon far fa-lightbulb" aria-hidden="true"></i>不要重复造轮子<i class="details-icon fas fa-angle-right" aria-hidden="true"></i>
    </div>
    <div class="details-content">
        <div class="admonition-content"><p>在动手写工具类之前，先看看成熟库是否已经提供了：</p>
<ul>
<li><strong>Hutool 5.8.44</strong>（2026-03-11）：国人开发的 Java 工具库，覆盖字符串、日期、加密、HTTP、JSON 等 90% 的工具需求，API 简洁</li>
<li><strong>Apache Commons</strong>：<code>commons-lang3</code>、<code>commons-io</code>、<code>commons-collections</code> 等，稳定可靠</li>
<li><strong>Guava</strong>：Google 的 Java 工具库，集合、缓存、并发工具强大</li>
</ul>
<p>本文在每个工具节的末尾都会给出&quot;成熟库替代方案&quot;，<strong>优先使用成熟库，只在特定需求时手写</strong>。</p>
</div>
    </div>
</div>
<hr>
<h2 id="二字符串工具">二、字符串工具</h2>
<h3 id="21-中文姓名转拼音生成邮箱账号">2.1 中文姓名转拼音生成邮箱账号</h3>
<p><strong>场景：</strong> 新员工入职系统自动生成企业邮箱，规则是&quot;名.姓@company.com&quot;，需要支持复姓（如诸葛孔明 → <a href="mailto:kongming.zhuge@company.com" rel="">kongming.zhuge@company.com</a>）。</p>
<div class="code-block code-line-numbers" 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">cn.hutool.extra.pinyin.PinyinUtil</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="kn">import</span><span class="w"> </span><span class="nn">java.util.Arrays</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">java.util.HashSet</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kn">import</span><span class="w"> </span><span class="nn">java.util.Set</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="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * 中文姓名转拼音邮箱账号工具
</span></span></span><span class="line"><span class="cl"><span class="cm"> *
</span></span></span><span class="line"><span class="cl"><span class="cm"> * 支持：
</span></span></span><span class="line"><span class="cl"><span class="cm"> * - 单姓：张三 → san.zhang
</span></span></span><span class="line"><span class="cl"><span class="cm"> * - 复姓：诸葛孔明 → kongming.zhuge
</span></span></span><span class="line"><span class="cl"><span class="cm"> * - 单名：张伟 → wei.zhang
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">PinyinEmailUtil</span><span class="w"> </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="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm">     * 中国常见复姓集合（可根据需要扩充）
</span></span></span><span class="line"><span class="cl"><span class="cm">     */</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">Set</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;</span><span class="w"> </span><span class="n">COMPOUND_SURNAMES</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">HashSet</span><span class="o">&lt;&gt;</span><span class="p">(</span><span class="n">Arrays</span><span class="p">.</span><span class="na">asList</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="s">&#34;欧阳&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;太史&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;端木&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;上官&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;司马&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;东方&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;独孤&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;南宫&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="s">&#34;万俟&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;闻人&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;夏侯&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;诸葛&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;尉迟&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公羊&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;赫连&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;澹台&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="s">&#34;皇甫&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;宗政&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;濮阳&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公冶&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;太叔&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;申屠&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公孙&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;慕容&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="s">&#34;仲孙&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;钟离&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;长孙&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;宇文&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;司徒&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;鲜于&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;司空&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;闾丘&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="s">&#34;子车&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;亓官&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;司寇&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;巫马&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公西&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;颛孙&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;壤驷&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公良&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="s">&#34;漆雕&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;乐正&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;宰父&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;谷梁&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;拓跋&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;夹谷&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;轩辕&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;令狐&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="s">&#34;段干&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;百里&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;呼延&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;东郭&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;南门&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;羊舌&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;微生&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公户&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="s">&#34;公玉&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公仪&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;梁丘&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公仲&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公上&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公门&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公山&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公坚&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="s">&#34;左丘&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公伯&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;西门&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公祖&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;第五&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公乘&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;贯丘&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;公皙&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="s">&#34;南荣&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;东里&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;东宫&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;仲长&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;子书&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;子桑&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;即墨&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;达奚&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="s">&#34;褚师&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </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="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm">     * 将中文姓名转换为拼音邮箱账号
</span></span></span><span class="line"><span class="cl"><span class="cm">     *
</span></span></span><span class="line"><span class="cl"><span class="cm">     * @param chineseName 中文姓名（如 &#34;诸葛孔明&#34;）
</span></span></span><span class="line"><span class="cl"><span class="cm">     * @param domain      邮箱域名（如 &#34;company.com&#34;）
</span></span></span><span class="line"><span class="cl"><span class="cm">     * @return 邮箱账号（如 &#34;kongming.zhuge@company.com&#34;）
</span></span></span><span class="line"><span class="cl"><span class="cm">     */</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="nf">toEmail</span><span class="p">(</span><span class="n">String</span><span class="w"> </span><span class="n">chineseName</span><span class="p">,</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="n">domain</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">chineseName</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">chineseName</span><span class="p">.</span><span class="na">length</span><span class="p">()</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">2</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="k">throw</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">IllegalArgumentException</span><span class="p">(</span><span class="s">&#34;姓名至少需要2个字符&#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="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="n">String</span><span class="w"> </span><span class="n">surname</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">String</span><span class="w"> </span><span class="n">givenName</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">// 判断是否为复姓（取前两个字匹配）</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">String</span><span class="w"> </span><span class="n">firstTwo</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">chineseName</span><span class="p">.</span><span class="na">substring</span><span class="p">(</span><span class="n">0</span><span class="p">,</span><span class="w"> </span><span class="n">2</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">COMPOUND_SURNAMES</span><span class="p">.</span><span class="na">contains</span><span class="p">(</span><span class="n">firstTwo</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">surname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">firstTwo</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">givenName</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">chineseName</span><span class="p">.</span><span class="na">substring</span><span class="p">(</span><span class="n">2</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="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">surname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">chineseName</span><span class="p">.</span><span class="na">substring</span><span class="p">(</span><span class="n">0</span><span class="p">,</span><span class="w"> </span><span class="n">1</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">givenName</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">chineseName</span><span class="p">.</span><span class="na">substring</span><span class="p">(</span><span class="n">1</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="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">// 转拼音（去掉声调，转小写）</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">String</span><span class="w"> </span><span class="n">surnamePinyin</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PinyinUtil</span><span class="p">.</span><span class="na">getPinyin</span><span class="p">(</span><span class="n">surname</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">String</span><span class="w"> </span><span class="n">givenNamePinyin</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">PinyinUtil</span><span class="p">.</span><span class="na">getPinyin</span><span class="p">(</span><span class="n">givenName</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;&#34;</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="k">return</span><span class="w"> </span><span class="n">givenNamePinyin</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s">&#34;.&#34;</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">surnamePinyin</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="s">&#34;@&#34;</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">domain</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="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="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm">     * 仅生成邮箱前缀（不含域名）
</span></span></span><span class="line"><span class="cl"><span class="cm">     */</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="nf">toEmailPrefix</span><span class="p">(</span><span class="n">String</span><span class="w"> </span><span class="n">chineseName</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">String</span><span class="w"> </span><span class="n">prefix</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">toEmail</span><span class="p">(</span><span class="n">chineseName</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;&#34;</span><span class="p">).</span><span class="na">replace</span><span class="p">(</span><span class="s">&#34;@&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c1">// 去除末尾可能多余的点号</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">prefix</span><span class="p">.</span><span class="na">endsWith</span><span class="p">(</span><span class="s">&#34;.&#34;</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="n">prefix</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">prefix</span><span class="p">.</span><span class="na">substring</span><span class="p">(</span><span class="n">0</span><span class="p">,</span><span class="w"> </span><span class="n">prefix</span><span class="p">.</span><span class="na">length</span><span class="p">()</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">1</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="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="w"> </span><span class="n">prefix</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="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span></span></span></code></pre></div></div>
<p><strong>使用示例：</strong></p>]]></description></item><item><title>信创项目实战总结：从申威龙芯到数据库三大件与容器化部署</title><link>https://oldletter.cn/posts/xinchuang-05-project-summary/</link><pubDate>Wed, 20 Aug 2025 00:00:00 +0000</pubDate><author>mumu</author><guid>https://oldletter.cn/posts/xinchuang-05-project-summary/</guid><description><![CDATA[<blockquote>
<p>作者：林 | 系列：信创实战 | 适合读者：信创项目实施者、Java 后端/架构师、运维工程师</p></blockquote>
<hr>
<h2 id="一背景为什么要做信创">一、背景：为什么要做信创</h2>
<p>信创（信息技术应用创新）的核心目标是<strong>自主可控</strong>。从芯片到操作系统，从数据库到中间件，逐步替换国外技术栈，降低供应链风险。</p>
<p>一个典型的信创项目涉及：</p>
<ul>
<li><strong>芯片</strong>：申威、龙芯、飞腾、鲲鹏、海光、兆芯</li>
<li><strong>操作系统</strong>：麒麟（银河麒麟/中标麒麟）、统信 UOS、欧拉</li>
<li><strong>数据库</strong>：达梦、人大金仓、神通</li>
<li><strong>中间件</strong>：东方通 TongWeb、宝兰德 BES</li>
<li><strong>办公软件</strong>：WPS、永中 Office</li>
<li><strong>可信计算</strong>：国密算法（SM2/SM3/SM4）、可信平台模块</li>
<li><strong>容器化</strong>：Docker 适配、镜像编译</li>
</ul>
<p>本文是实际项目中的踩坑总结，重点覆盖申威、龙芯、数据库三大件和容器化部署。</p>
<hr>
<h2 id="二国产-cpu-处理器选型">二、国产 CPU 处理器选型</h2>
<h3 id="21-六大国产-cpu-对比">2.1 六大国产 CPU 对比</h3>
<table>
  <thead>
      <tr>
          <th>厂商</th>
          <th>指令集</th>
          <th>代表型号</th>
          <th>定位</th>
          <th>生态成熟度</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>申威</strong></td>
          <td>SW64（自主）</td>
          <td>SW1621、SW3231、HX 系列</td>
          <td>特种/超算/信创</td>
          <td>⭐⭐</td>
      </tr>
      <tr>
          <td><strong>龙芯</strong></td>
          <td>LoongArch（自主）</td>
          <td>3A5000、3C5000、3A6000、3C6000</td>
          <td>桌面/服务器</td>
          <td>⭐⭐⭐</td>
      </tr>
      <tr>
          <td><strong>飞腾</strong></td>
          <td>ARMv8/AArch64（授权）</td>
          <td>FT-2000、S2500</td>
          <td>桌面/服务器</td>
          <td>⭐⭐⭐⭐</td>
      </tr>
      <tr>
          <td><strong>鲲鹏</strong></td>
          <td>ARMv8/AArch64（授权）</td>
          <td>鲲鹏 920</td>
          <td>服务器</td>
          <td>⭐⭐⭐⭐</td>
      </tr>
      <tr>
          <td><strong>海光</strong></td>
          <td>x86（授权）</td>
          <td>海光 7000、海光 5000</td>
          <td>服务器</td>
          <td>⭐⭐⭐⭐⭐</td>
      </tr>
      <tr>
          <td><strong>兆芯</strong></td>
          <td>x86（授权）</td>
          <td>开胜 KH-40000</td>
          <td>桌面/服务器</td>
          <td>⭐⭐⭐⭐</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p>⚠️ 注意：海光和兆芯的 x86 授权有争议（AMD/VIA 授权），严格意义上不算&quot;完全自主&quot;。部分信创项目不接受 x86 路线。</p>]]></description></item><item><title>国密实战（一）：SM2 密钥格式与 PFX 证书解析全指南</title><link>https://oldletter.cn/posts/guomi-01-sm2-key-cert/</link><pubDate>Thu, 10 Mar 2022 00:00:00 +0000</pubDate><author>mumu</author><guid>https://oldletter.cn/posts/guomi-01-sm2-key-cert/</guid><description><![CDATA[<blockquote>
<p>作者：林 | 系列：国密实战 | 适合读者：Java 后端/架构师</p></blockquote>
<hr>
<h2 id="一背景与问题">一、背景与问题</h2>
<p>随着《密码法》的实施和信创（信息技术应用创新）要求的推进，越来越多的政府、央企、金融项目要求使用<strong>国密算法</strong>替代 RSA/ECDSA。SM2 作为国密体系中的非对称加密算法，对标 RSA-2048 和 ECDSA P-256，已广泛应用于数字证书、签名验签、密钥交换等场景。</p>
<p>然而，在实际项目中接入 SM2 时，第一个拦路虎往往并非算法本身，重点是，<strong>密钥格式和证书解析</strong>。不同厂商输出的密钥格式不一致（hex、DER、PEM），PFX 证书里封装的 SM2 密钥对解析方式与 RSA 也有差异，稍不注意就会踩坑。</p>
<p>本文将系统梳理 SM2 密钥格式，并给出从 PFX 证书中提取 SM2 公私钥的完整 Java 实现。</p>
<hr>
<h2 id="二sm2-算法简介">二、SM2 算法简介</h2>
<p>SM2 是国家密码管理局发布的椭圆曲线公钥密码算法，标准编号 <strong>GM/T 0003</strong>，包含：</p>
<table>
  <thead>
      <tr>
          <th>部分</th>
          <th>内容</th>
          <th>对标国际标准</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>GM/T 0003.1</td>
          <td>总则</td>
          <td>—</td>
      </tr>
      <tr>
          <td>GM/T 0003.2</td>
          <td>数字签名算法</td>
          <td>ECDSA</td>
      </tr>
      <tr>
          <td>GM/T 0003.3</td>
          <td>密钥交换协议</td>
          <td>ECDH</td>
      </tr>
      <tr>
          <td>GM/T 0003.4</td>
          <td>公钥加密算法</td>
          <td>ECIES</td>
      </tr>
      <tr>
          <td>GM/T 0003.5</td>
          <td>参数定义</td>
          <td>—</td>
      </tr>
  </tbody>
</table>
<p>SM2 使用的椭圆曲线参数为 <code>sm2p256v1</code>，其曲线方程为标准 Weierstrass 形式：y² = x³ + ax + b (mod p)。</p>]]></description></item><item><title>国密实战（二）：SM2 签名验签前后端对接全指南</title><link>https://oldletter.cn/posts/guomi-02-sm2-sign-verify/</link><pubDate>Wed, 15 Jun 2022 00:00:00 +0000</pubDate><author>mumu</author><guid>https://oldletter.cn/posts/guomi-02-sm2-sign-verify/</guid><description><![CDATA[<blockquote>
<p>作者：林 | 系列：国密实战 | 适合读者：Java 后端/架构师 + 前端开发者</p></blockquote>
<hr>
<h2 id="一背景与问题">一、背景与问题</h2>
<p>在很多业务场景中，前端需要对请求参数进行签名，后端进行验签，以确保数据完整性和防篡改。传统方案多使用 RSA 签名，但在信创项目中，SM2 签名验签成为必选项。</p>
<p><strong>典型场景</strong>：</p>
<ul>
<li>前端提交表单数据，附带 SM2 签名</li>
<li>后端验签通过后才处理业务逻辑</li>
<li>API 网关层面的请求签名校验</li>
<li>合同/文档电子签章</li>
</ul>
<p>前后端对接 SM2 签名验签的核心挑战：</p>
<ol>
<li><strong>库的选择</strong>：Java 端用什么库？前端用什么库？</li>
<li><strong>密钥格式约定</strong>：私钥和公钥的格式必须统一</li>
<li><strong>userId 的一致性</strong>：SM2 签名有一个独特的 <code>userId</code> 参数，两端必须一致</li>
<li><strong>hash 参数的一致性</strong>：是否对消息做预哈希，两端必须统一</li>
<li><strong>签名格式</strong>：<code>r || s</code> 拼接 vs DER 编码，两端必须约定</li>
</ol>
<p>本文将给出 Java（Hutool）+ TypeScript（sm-crypto）的完整对接方案。</p>
<hr>
<h2 id="二sm2-签名验签原理">二、SM2 签名验签原理</h2>
<h3 id="21-签名过程">2.1 签名过程</h3>
<p>SM2 签名过程比 ECDSA 多了一个 <strong>Z 值</strong>（用户标识哈希）的计算。完整流程如下：</p>
<p><strong>输入参数</strong>：</p>
<ul>
<li>待签名消息 M</li>
<li>用户标识 ID（默认 <code>&quot;1234567812345678&quot;</code>）</li>
<li>私钥 d（256 位整数）</li>
<li>公钥 P = d × G = (xA, yA）</li>
</ul>
<p><strong>步骤</strong>：</p>]]></description></item><item><title>国密实战（三）：SM2+SM4 数字信封完整实现（对接国企实战）</title><link>https://oldletter.cn/posts/guomi-03-sm2-sm4-envelope/</link><pubDate>Thu, 15 Dec 2022 00:00:00 +0000</pubDate><author>mumu</author><guid>https://oldletter.cn/posts/guomi-03-sm2-sm4-envelope/</guid><description><![CDATA[<blockquote>
<p>作者：林 | 系列：国密实战 | 适合读者：Java 后端/架构师</p></blockquote>
<hr>
<h2 id="一背景与问题">一、背景与问题</h2>
<p>在国企、央企、政府项目的接口对接中，数据传输的安全性要求通常采用<strong>数字信封</strong>（Digital Envelope）机制：使用非对称算法加密对称密钥，再用对称密钥加密业务数据。这既保证了密钥传输的安全性，又兼顾了大数据量加密的性能。</p>
<p>在国密体系中，这个组合就是 <strong>SM2 + SM4</strong>：</p>
<ul>
<li><strong>SM4</strong>：对称加密算法，负责加密业务数据（高效）</li>
<li><strong>SM2</strong>：非对称加密算法，负责加密 SM4 密钥（安全）</li>
</ul>
<h3 id="11-为什么需要数字信封">1.1 为什么需要数字信封？</h3>
<table>
  <thead>
      <tr>
          <th>方案</th>
          <th style="text-align: center">安全性</th>
          <th style="text-align: center">性能</th>
          <th>适用场景</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>直接 SM2 加密数据</td>
          <td style="text-align: center">✅ 高</td>
          <td style="text-align: center">❌ 差（数据量受限）</td>
          <td>小数据（如密钥）</td>
      </tr>
      <tr>
          <td>直接 SM4 加密数据</td>
          <td style="text-align: center">❌ 密钥如何安全传输？</td>
          <td style="text-align: center">✅ 好</td>
          <td>需要解决密钥分发问题</td>
      </tr>
      <tr>
          <td><strong>SM2+SM4 数字信封</strong></td>
          <td style="text-align: center">✅ 高</td>
          <td style="text-align: center">✅ 好</td>
          <td><strong>大数据量 + 高安全性</strong></td>
      </tr>
  </tbody>
</table>
<p>SM2 加密的数据长度受限，上限明文长度约为 <strong>256 字节</strong>（受椭圆曲线参数限制）。不适合直接加密业务数据。而 SM4 虽然性能好，但密钥需要安全传输。数字信封完美结合了两者的优势。</p>
<p>SM2 加密数据长度计算：密文长度 = 65（C1，临时公钥点）+ 32（C3，SM3 哈希）+ n = 97 + n bytes。其中 n 为明文长度。加密 16 字节 SM4 密钥时，密文为 97 + 16 = 113 字节。</p>]]></description></item></channel></rss>