C#实现SM4国密加密
<p>本文主要讲解“国密加密算法”SM系列之SM4的C#实现方法,加密规则请详阅国密局发布的文档。</p><p>首先需第三方Nuget包:<span style="color: rgba(255, 102, 0, 1)">Portable.BouncyCastle</span> (源码来自http://www.bouncycastle.org/csharp/)</p>
<p>1.1 SM4主类</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">internal</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> SM4
{
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 加密 非线性τ函数B=τ(A)
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="b"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="i"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">long</span> GetULongByBe(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] b, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> i)
{
</span><span style="color: rgba(0, 0, 255, 1)">long</span> n = (<span style="color: rgba(0, 0, 255, 1)">long</span>)(b & <span style="color: rgba(128, 0, 128, 1)">0xff</span>) << <span style="color: rgba(128, 0, 128, 1)">24</span> |<span style="color: rgba(0, 0, 0, 1)">
(</span><span style="color: rgba(0, 0, 255, 1)">long</span>)((b & <span style="color: rgba(128, 0, 128, 1)">0xff</span>) << <span style="color: rgba(128, 0, 128, 1)">16</span>) |<span style="color: rgba(0, 0, 0, 1)">
(</span><span style="color: rgba(0, 0, 255, 1)">long</span>)((b & <span style="color: rgba(128, 0, 128, 1)">0xff</span>) << <span style="color: rgba(128, 0, 128, 1)">8</span>) |<span style="color: rgba(0, 0, 0, 1)">
(</span><span style="color: rgba(0, 0, 255, 1)">long</span>)(b & <span style="color: rgba(128, 0, 128, 1)">0xff</span>) & <span style="color: rgba(128, 0, 128, 1)">0xffffffffL</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> n;
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 解密 非线性τ函数B=τ(A)
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="n"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="b"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="i"></param></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> PutULongToBe(<span style="color: rgba(0, 0, 255, 1)">long</span> n, <span style="color: rgba(0, 0, 255, 1)">byte</span>[] b, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> i)
{
b </span>= (<span style="color: rgba(0, 0, 255, 1)">byte</span>)(<span style="color: rgba(0, 0, 255, 1)">int</span>)(<span style="color: rgba(128, 0, 128, 1)">0xFF</span> & n >> <span style="color: rgba(128, 0, 128, 1)">24</span><span style="color: rgba(0, 0, 0, 1)">);
b = (<span style="color: rgba(0, 0, 255, 1)">byte</span>)(<span style="color: rgba(0, 0, 255, 1)">int</span>)(<span style="color: rgba(128, 0, 128, 1)">0xFF</span> & n >> <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
b = (<span style="color: rgba(0, 0, 255, 1)">byte</span>)(<span style="color: rgba(0, 0, 255, 1)">int</span>)(<span style="color: rgba(128, 0, 128, 1)">0xFF</span> & n >> <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">);
b = (<span style="color: rgba(0, 0, 255, 1)">byte</span>)(<span style="color: rgba(0, 0, 255, 1)">int</span>)(<span style="color: rgba(128, 0, 128, 1)">0xFF</span> &<span style="color: rgba(0, 0, 0, 1)"> n);
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 循环移位,为32位的x循环左移n位
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="x"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="n"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">long</span> Rotl(<span style="color: rgba(0, 0, 255, 1)">long</span> x, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> n)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> ((x & <span style="color: rgba(128, 0, 128, 1)">0xFFFFFFFF</span>) << n) | x >> (<span style="color: rgba(128, 0, 128, 1)">32</span> -<span style="color: rgba(0, 0, 0, 1)"> n);
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 将密钥逆序
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="sk"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="i"></param></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Swap(<span style="color: rgba(0, 0, 255, 1)">long</span>[] sk, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> i)
{
</span><span style="color: rgba(0, 0, 255, 1)">long</span> t =<span style="color: rgba(0, 0, 0, 1)"> sk;
sk </span>= sk[(<span style="color: rgba(128, 0, 128, 1)">31</span> -<span style="color: rgba(0, 0, 0, 1)"> i)];
sk[(</span><span style="color: rgba(128, 0, 128, 1)">31</span> - i)] =<span style="color: rgba(0, 0, 0, 1)"> t;
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> S盒
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] SboxTable = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 0 1 2 3 4 5 6 7 8 9 a b c d e f</span>
<span style="color: rgba(128, 0, 128, 1)">0xd6</span>, <span style="color: rgba(128, 0, 128, 1)">0x90</span>, <span style="color: rgba(128, 0, 128, 1)">0xe9</span>, <span style="color: rgba(128, 0, 128, 1)">0xfe</span>, <span style="color: rgba(128, 0, 128, 1)">0xcc</span>, <span style="color: rgba(128, 0, 128, 1)">0xe1</span>, <span style="color: rgba(128, 0, 128, 1)">0x3d</span>, <span style="color: rgba(128, 0, 128, 1)">0xb7</span>, <span style="color: rgba(128, 0, 128, 1)">0x16</span>, <span style="color: rgba(128, 0, 128, 1)">0xb6</span>, <span style="color: rgba(128, 0, 128, 1)">0x14</span>, <span style="color: rgba(128, 0, 128, 1)">0xc2</span>, <span style="color: rgba(128, 0, 128, 1)">0x28</span>, <span style="color: rgba(128, 0, 128, 1)">0xfb</span>, <span style="color: rgba(128, 0, 128, 1)">0x2c</span>, <span style="color: rgba(128, 0, 128, 1)">0x05</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x2b</span>, <span style="color: rgba(128, 0, 128, 1)">0x67</span>, <span style="color: rgba(128, 0, 128, 1)">0x9a</span>, <span style="color: rgba(128, 0, 128, 1)">0x76</span>, <span style="color: rgba(128, 0, 128, 1)">0x2a</span>, <span style="color: rgba(128, 0, 128, 1)">0xbe</span>, <span style="color: rgba(128, 0, 128, 1)">0x04</span>, <span style="color: rgba(128, 0, 128, 1)">0xc3</span>, <span style="color: rgba(128, 0, 128, 1)">0xaa</span>, <span style="color: rgba(128, 0, 128, 1)">0x44</span>, <span style="color: rgba(128, 0, 128, 1)">0x13</span>, <span style="color: rgba(128, 0, 128, 1)">0x26</span>, <span style="color: rgba(128, 0, 128, 1)">0x49</span>, <span style="color: rgba(128, 0, 128, 1)">0x86</span>, <span style="color: rgba(128, 0, 128, 1)">0x06</span>, <span style="color: rgba(128, 0, 128, 1)">0x99</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x9c</span>, <span style="color: rgba(128, 0, 128, 1)">0x42</span>, <span style="color: rgba(128, 0, 128, 1)">0x50</span>, <span style="color: rgba(128, 0, 128, 1)">0xf4</span>, <span style="color: rgba(128, 0, 128, 1)">0x91</span>, <span style="color: rgba(128, 0, 128, 1)">0xef</span>, <span style="color: rgba(128, 0, 128, 1)">0x98</span>, <span style="color: rgba(128, 0, 128, 1)">0x7a</span>, <span style="color: rgba(128, 0, 128, 1)">0x33</span>, <span style="color: rgba(128, 0, 128, 1)">0x54</span>, <span style="color: rgba(128, 0, 128, 1)">0x0b</span>, <span style="color: rgba(128, 0, 128, 1)">0x43</span>, <span style="color: rgba(128, 0, 128, 1)">0xed</span>, <span style="color: rgba(128, 0, 128, 1)">0xcf</span>, <span style="color: rgba(128, 0, 128, 1)">0xac</span>, <span style="color: rgba(128, 0, 128, 1)">0x62</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0xe4</span>, <span style="color: rgba(128, 0, 128, 1)">0xb3</span>, <span style="color: rgba(128, 0, 128, 1)">0x1c</span>, <span style="color: rgba(128, 0, 128, 1)">0xa9</span>, <span style="color: rgba(128, 0, 128, 1)">0xc9</span>, <span style="color: rgba(128, 0, 128, 1)">0x08</span>, <span style="color: rgba(128, 0, 128, 1)">0xe8</span>, <span style="color: rgba(128, 0, 128, 1)">0x95</span>, <span style="color: rgba(128, 0, 128, 1)">0x80</span>, <span style="color: rgba(128, 0, 128, 1)">0xdf</span>, <span style="color: rgba(128, 0, 128, 1)">0x94</span>, <span style="color: rgba(128, 0, 128, 1)">0xfa</span>, <span style="color: rgba(128, 0, 128, 1)">0x75</span>, <span style="color: rgba(128, 0, 128, 1)">0x8f</span>, <span style="color: rgba(128, 0, 128, 1)">0x3f</span>, <span style="color: rgba(128, 0, 128, 1)">0xa6</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x47</span>, <span style="color: rgba(128, 0, 128, 1)">0x07</span>, <span style="color: rgba(128, 0, 128, 1)">0xa7</span>, <span style="color: rgba(128, 0, 128, 1)">0xfc</span>, <span style="color: rgba(128, 0, 128, 1)">0xf3</span>, <span style="color: rgba(128, 0, 128, 1)">0x73</span>, <span style="color: rgba(128, 0, 128, 1)">0x17</span>, <span style="color: rgba(128, 0, 128, 1)">0xba</span>, <span style="color: rgba(128, 0, 128, 1)">0x83</span>, <span style="color: rgba(128, 0, 128, 1)">0x59</span>, <span style="color: rgba(128, 0, 128, 1)">0x3c</span>, <span style="color: rgba(128, 0, 128, 1)">0x19</span>, <span style="color: rgba(128, 0, 128, 1)">0xe6</span>, <span style="color: rgba(128, 0, 128, 1)">0x85</span>, <span style="color: rgba(128, 0, 128, 1)">0x4f</span>, <span style="color: rgba(128, 0, 128, 1)">0xa8</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x68</span>, <span style="color: rgba(128, 0, 128, 1)">0x6b</span>, <span style="color: rgba(128, 0, 128, 1)">0x81</span>, <span style="color: rgba(128, 0, 128, 1)">0xb2</span>, <span style="color: rgba(128, 0, 128, 1)">0x71</span>, <span style="color: rgba(128, 0, 128, 1)">0x64</span>, <span style="color: rgba(128, 0, 128, 1)">0xda</span>, <span style="color: rgba(128, 0, 128, 1)">0x8b</span>, <span style="color: rgba(128, 0, 128, 1)">0xf8</span>, <span style="color: rgba(128, 0, 128, 1)">0xeb</span>, <span style="color: rgba(128, 0, 128, 1)">0x0f</span>, <span style="color: rgba(128, 0, 128, 1)">0x4b</span>, <span style="color: rgba(128, 0, 128, 1)">0x70</span>, <span style="color: rgba(128, 0, 128, 1)">0x56</span>, <span style="color: rgba(128, 0, 128, 1)">0x9d</span>, <span style="color: rgba(128, 0, 128, 1)">0x35</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x1e</span>, <span style="color: rgba(128, 0, 128, 1)">0x24</span>, <span style="color: rgba(128, 0, 128, 1)">0x0e</span>, <span style="color: rgba(128, 0, 128, 1)">0x5e</span>, <span style="color: rgba(128, 0, 128, 1)">0x63</span>, <span style="color: rgba(128, 0, 128, 1)">0x58</span>, <span style="color: rgba(128, 0, 128, 1)">0xd1</span>, <span style="color: rgba(128, 0, 128, 1)">0xa2</span>, <span style="color: rgba(128, 0, 128, 1)">0x25</span>, <span style="color: rgba(128, 0, 128, 1)">0x22</span>, <span style="color: rgba(128, 0, 128, 1)">0x7c</span>, <span style="color: rgba(128, 0, 128, 1)">0x3b</span>, <span style="color: rgba(128, 0, 128, 1)">0x01</span>, <span style="color: rgba(128, 0, 128, 1)">0x21</span>, <span style="color: rgba(128, 0, 128, 1)">0x78</span>, <span style="color: rgba(128, 0, 128, 1)">0x87</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0xd4</span>, <span style="color: rgba(128, 0, 128, 1)">0x00</span>, <span style="color: rgba(128, 0, 128, 1)">0x46</span>, <span style="color: rgba(128, 0, 128, 1)">0x57</span>, <span style="color: rgba(128, 0, 128, 1)">0x9f</span>, <span style="color: rgba(128, 0, 128, 1)">0xd3</span>, <span style="color: rgba(128, 0, 128, 1)">0x27</span>, <span style="color: rgba(128, 0, 128, 1)">0x52</span>, <span style="color: rgba(128, 0, 128, 1)">0x4c</span>, <span style="color: rgba(128, 0, 128, 1)">0x36</span>, <span style="color: rgba(128, 0, 128, 1)">0x02</span>, <span style="color: rgba(128, 0, 128, 1)">0xe7</span>, <span style="color: rgba(128, 0, 128, 1)">0xa0</span>, <span style="color: rgba(128, 0, 128, 1)">0xc4</span>, <span style="color: rgba(128, 0, 128, 1)">0xc8</span>, <span style="color: rgba(128, 0, 128, 1)">0x9e</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0xea</span>, <span style="color: rgba(128, 0, 128, 1)">0xbf</span>, <span style="color: rgba(128, 0, 128, 1)">0x8a</span>, <span style="color: rgba(128, 0, 128, 1)">0xd2</span>, <span style="color: rgba(128, 0, 128, 1)">0x40</span>, <span style="color: rgba(128, 0, 128, 1)">0xc7</span>, <span style="color: rgba(128, 0, 128, 1)">0x38</span>, <span style="color: rgba(128, 0, 128, 1)">0xb5</span>, <span style="color: rgba(128, 0, 128, 1)">0xa3</span>, <span style="color: rgba(128, 0, 128, 1)">0xf7</span>, <span style="color: rgba(128, 0, 128, 1)">0xf2</span>, <span style="color: rgba(128, 0, 128, 1)">0xce</span>, <span style="color: rgba(128, 0, 128, 1)">0xf9</span>, <span style="color: rgba(128, 0, 128, 1)">0x61</span>, <span style="color: rgba(128, 0, 128, 1)">0x15</span>, <span style="color: rgba(128, 0, 128, 1)">0xa1</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0xe0</span>, <span style="color: rgba(128, 0, 128, 1)">0xae</span>, <span style="color: rgba(128, 0, 128, 1)">0x5d</span>, <span style="color: rgba(128, 0, 128, 1)">0xa4</span>, <span style="color: rgba(128, 0, 128, 1)">0x9b</span>, <span style="color: rgba(128, 0, 128, 1)">0x34</span>, <span style="color: rgba(128, 0, 128, 1)">0x1a</span>, <span style="color: rgba(128, 0, 128, 1)">0x55</span>, <span style="color: rgba(128, 0, 128, 1)">0xad</span>, <span style="color: rgba(128, 0, 128, 1)">0x93</span>, <span style="color: rgba(128, 0, 128, 1)">0x32</span>, <span style="color: rgba(128, 0, 128, 1)">0x30</span>, <span style="color: rgba(128, 0, 128, 1)">0xf5</span>, <span style="color: rgba(128, 0, 128, 1)">0x8c</span>, <span style="color: rgba(128, 0, 128, 1)">0xb1</span>, <span style="color: rgba(128, 0, 128, 1)">0xe3</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x1d</span>, <span style="color: rgba(128, 0, 128, 1)">0xf6</span>, <span style="color: rgba(128, 0, 128, 1)">0xe2</span>, <span style="color: rgba(128, 0, 128, 1)">0x2e</span>, <span style="color: rgba(128, 0, 128, 1)">0x82</span>, <span style="color: rgba(128, 0, 128, 1)">0x66</span>, <span style="color: rgba(128, 0, 128, 1)">0xca</span>, <span style="color: rgba(128, 0, 128, 1)">0x60</span>, <span style="color: rgba(128, 0, 128, 1)">0xc0</span>, <span style="color: rgba(128, 0, 128, 1)">0x29</span>, <span style="color: rgba(128, 0, 128, 1)">0x23</span>, <span style="color: rgba(128, 0, 128, 1)">0xab</span>, <span style="color: rgba(128, 0, 128, 1)">0x0d</span>, <span style="color: rgba(128, 0, 128, 1)">0x53</span>, <span style="color: rgba(128, 0, 128, 1)">0x4e</span>, <span style="color: rgba(128, 0, 128, 1)">0x6f</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0xd5</span>, <span style="color: rgba(128, 0, 128, 1)">0xdb</span>, <span style="color: rgba(128, 0, 128, 1)">0x37</span>, <span style="color: rgba(128, 0, 128, 1)">0x45</span>, <span style="color: rgba(128, 0, 128, 1)">0xde</span>, <span style="color: rgba(128, 0, 128, 1)">0xfd</span>, <span style="color: rgba(128, 0, 128, 1)">0x8e</span>, <span style="color: rgba(128, 0, 128, 1)">0x2f</span>, <span style="color: rgba(128, 0, 128, 1)">0x03</span>, <span style="color: rgba(128, 0, 128, 1)">0xff</span>, <span style="color: rgba(128, 0, 128, 1)">0x6a</span>, <span style="color: rgba(128, 0, 128, 1)">0x72</span>, <span style="color: rgba(128, 0, 128, 1)">0x6d</span>, <span style="color: rgba(128, 0, 128, 1)">0x6c</span>, <span style="color: rgba(128, 0, 128, 1)">0x5b</span>, <span style="color: rgba(128, 0, 128, 1)">0x51</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x8d</span>, <span style="color: rgba(128, 0, 128, 1)">0x1b</span>, <span style="color: rgba(128, 0, 128, 1)">0xaf</span>, <span style="color: rgba(128, 0, 128, 1)">0x92</span>, <span style="color: rgba(128, 0, 128, 1)">0xbb</span>, <span style="color: rgba(128, 0, 128, 1)">0xdd</span>, <span style="color: rgba(128, 0, 128, 1)">0xbc</span>, <span style="color: rgba(128, 0, 128, 1)">0x7f</span>, <span style="color: rgba(128, 0, 128, 1)">0x11</span>, <span style="color: rgba(128, 0, 128, 1)">0xd9</span>, <span style="color: rgba(128, 0, 128, 1)">0x5c</span>, <span style="color: rgba(128, 0, 128, 1)">0x41</span>, <span style="color: rgba(128, 0, 128, 1)">0x1f</span>, <span style="color: rgba(128, 0, 128, 1)">0x10</span>, <span style="color: rgba(128, 0, 128, 1)">0x5a</span>, <span style="color: rgba(128, 0, 128, 1)">0xd8</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x0a</span>, <span style="color: rgba(128, 0, 128, 1)">0xc1</span>, <span style="color: rgba(128, 0, 128, 1)">0x31</span>, <span style="color: rgba(128, 0, 128, 1)">0x88</span>, <span style="color: rgba(128, 0, 128, 1)">0xa5</span>, <span style="color: rgba(128, 0, 128, 1)">0xcd</span>, <span style="color: rgba(128, 0, 128, 1)">0x7b</span>, <span style="color: rgba(128, 0, 128, 1)">0xbd</span>, <span style="color: rgba(128, 0, 128, 1)">0x2d</span>, <span style="color: rgba(128, 0, 128, 1)">0x74</span>, <span style="color: rgba(128, 0, 128, 1)">0xd0</span>, <span style="color: rgba(128, 0, 128, 1)">0x12</span>, <span style="color: rgba(128, 0, 128, 1)">0xb8</span>, <span style="color: rgba(128, 0, 128, 1)">0xe5</span>, <span style="color: rgba(128, 0, 128, 1)">0xb4</span>, <span style="color: rgba(128, 0, 128, 1)">0xb0</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x89</span>, <span style="color: rgba(128, 0, 128, 1)">0x69</span>, <span style="color: rgba(128, 0, 128, 1)">0x97</span>, <span style="color: rgba(128, 0, 128, 1)">0x4a</span>, <span style="color: rgba(128, 0, 128, 1)">0x0c</span>, <span style="color: rgba(128, 0, 128, 1)">0x96</span>, <span style="color: rgba(128, 0, 128, 1)">0x77</span>, <span style="color: rgba(128, 0, 128, 1)">0x7e</span>, <span style="color: rgba(128, 0, 128, 1)">0x65</span>, <span style="color: rgba(128, 0, 128, 1)">0xb9</span>, <span style="color: rgba(128, 0, 128, 1)">0xf1</span>, <span style="color: rgba(128, 0, 128, 1)">0x09</span>, <span style="color: rgba(128, 0, 128, 1)">0xc5</span>, <span style="color: rgba(128, 0, 128, 1)">0x6e</span>, <span style="color: rgba(128, 0, 128, 1)">0xc6</span>, <span style="color: rgba(128, 0, 128, 1)">0x84</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x18</span>, <span style="color: rgba(128, 0, 128, 1)">0xf0</span>, <span style="color: rgba(128, 0, 128, 1)">0x7d</span>, <span style="color: rgba(128, 0, 128, 1)">0xec</span>, <span style="color: rgba(128, 0, 128, 1)">0x3a</span>, <span style="color: rgba(128, 0, 128, 1)">0xdc</span>, <span style="color: rgba(128, 0, 128, 1)">0x4d</span>, <span style="color: rgba(128, 0, 128, 1)">0x20</span>, <span style="color: rgba(128, 0, 128, 1)">0x79</span>, <span style="color: rgba(128, 0, 128, 1)">0xee</span>, <span style="color: rgba(128, 0, 128, 1)">0x5f</span>, <span style="color: rgba(128, 0, 128, 1)">0x3e</span>, <span style="color: rgba(128, 0, 128, 1)">0xd7</span>, <span style="color: rgba(128, 0, 128, 1)">0xcb</span>, <span style="color: rgba(128, 0, 128, 1)">0x39</span>, <span style="color: rgba(128, 0, 128, 1)">0x48</span><span style="color: rgba(0, 0, 0, 1)">
};
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 系统参数FK
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">uint</span>[] FK = { <span style="color: rgba(128, 0, 128, 1)">0xa3b1bac6</span>, <span style="color: rgba(128, 0, 128, 1)">0x56aa3350</span>, <span style="color: rgba(128, 0, 128, 1)">0x677d9197</span>, <span style="color: rgba(128, 0, 128, 1)">0xb27022dc</span><span style="color: rgba(0, 0, 0, 1)"> };
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 固定参数CK
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">uint</span>[] CK =<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(128, 0, 128, 1)">0x00070e15</span>,<span style="color: rgba(128, 0, 128, 1)">0x1c232a31</span>,<span style="color: rgba(128, 0, 128, 1)">0x383f464d</span>,<span style="color: rgba(128, 0, 128, 1)">0x545b6269</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x70777e85</span>,<span style="color: rgba(128, 0, 128, 1)">0x8c939aa1</span>,<span style="color: rgba(128, 0, 128, 1)">0xa8afb6bd</span>,<span style="color: rgba(128, 0, 128, 1)">0xc4cbd2d9</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0xe0e7eef5</span>,<span style="color: rgba(128, 0, 128, 1)">0xfc030a11</span>,<span style="color: rgba(128, 0, 128, 1)">0x181f262d</span>,<span style="color: rgba(128, 0, 128, 1)">0x343b4249</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x50575e65</span>,<span style="color: rgba(128, 0, 128, 1)">0x6c737a81</span>,<span style="color: rgba(128, 0, 128, 1)">0x888f969d</span>,<span style="color: rgba(128, 0, 128, 1)">0xa4abb2b9</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0xc0c7ced5</span>,<span style="color: rgba(128, 0, 128, 1)">0xdce3eaf1</span>,<span style="color: rgba(128, 0, 128, 1)">0xf8ff060d</span>,<span style="color: rgba(128, 0, 128, 1)">0x141b2229</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x30373e45</span>,<span style="color: rgba(128, 0, 128, 1)">0x4c535a61</span>,<span style="color: rgba(128, 0, 128, 1)">0x686f767d</span>,<span style="color: rgba(128, 0, 128, 1)">0x848b9299</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0xa0a7aeb5</span>,<span style="color: rgba(128, 0, 128, 1)">0xbcc3cad1</span>,<span style="color: rgba(128, 0, 128, 1)">0xd8dfe6ed</span>,<span style="color: rgba(128, 0, 128, 1)">0xf4fb0209</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 0, 128, 1)">0x10171e25</span>,<span style="color: rgba(128, 0, 128, 1)">0x2c333a41</span>,<span style="color: rgba(128, 0, 128, 1)">0x484f565d</span>,<span style="color: rgba(128, 0, 128, 1)">0x646b7279</span><span style="color: rgba(0, 0, 0, 1)">
};
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> Sm4的S盒取值
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="inch"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">byte</span> Sm4Sbox(<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)"> inch)
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> i = inch & <span style="color: rgba(128, 0, 128, 1)">0xFF</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span> retVal =<span style="color: rgba(0, 0, 0, 1)"> SboxTable;
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> retVal;
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 线性变换 L
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="ka"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">long</span> Sm4Lt(<span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)"> ka)
{
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] a = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] b = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">];
PutULongToBe(ka, a, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
b[</span><span style="color: rgba(128, 0, 128, 1)">0</span>] = Sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">]);
b[</span><span style="color: rgba(128, 0, 128, 1)">1</span>] = Sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">]);
b[</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = Sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">]);
b[</span><span style="color: rgba(128, 0, 128, 1)">3</span>] = Sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">]);
</span><span style="color: rgba(0, 0, 255, 1)">long</span> bb = GetULongByBe(b, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">long</span> c = bb ^ Rotl(bb, <span style="color: rgba(128, 0, 128, 1)">2</span>) ^ Rotl(bb, <span style="color: rgba(128, 0, 128, 1)">10</span>) ^ Rotl(bb, <span style="color: rgba(128, 0, 128, 1)">18</span>) ^ Rotl(bb, <span style="color: rgba(128, 0, 128, 1)">24</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> c;
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 轮函数 F
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="x0"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="x1"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="x2"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="x3"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="rk"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">long</span> Sm4F(<span style="color: rgba(0, 0, 255, 1)">long</span> x0, <span style="color: rgba(0, 0, 255, 1)">long</span> x1, <span style="color: rgba(0, 0, 255, 1)">long</span> x2, <span style="color: rgba(0, 0, 255, 1)">long</span> x3, <span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)"> rk)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> x0 ^ Sm4Lt(x1 ^ x2 ^ x3 ^<span style="color: rgba(0, 0, 0, 1)"> rk);
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 轮密钥rk
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="ka"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">long</span> Sm4CalciRk(<span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)"> ka)
{
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] a = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] b = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">];
PutULongToBe(ka, a, </span><span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
b[</span><span style="color: rgba(128, 0, 128, 1)">0</span>] = Sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">]);
b[</span><span style="color: rgba(128, 0, 128, 1)">1</span>] = Sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">]);
b[</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = Sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">]);
b[</span><span style="color: rgba(128, 0, 128, 1)">3</span>] = Sm4Sbox(a[<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">]);
</span><span style="color: rgba(0, 0, 255, 1)">long</span> bb = GetULongByBe(b, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">long</span> rk = bb ^ Rotl(bb, <span style="color: rgba(128, 0, 128, 1)">13</span>) ^ Rotl(bb, <span style="color: rgba(128, 0, 128, 1)">23</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> rk;
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 加密密钥
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="SK"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="key"></param></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SetKey(<span style="color: rgba(0, 0, 255, 1)">long</span>[] SK, <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] key)
{
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">加密密钥长度为 128 比特</span>
<span style="color: rgba(0, 0, 255, 1)">long</span>[] MK = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">long</span>[<span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
MK[</span><span style="color: rgba(128, 0, 128, 1)">0</span>] = GetULongByBe(key, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
MK[</span><span style="color: rgba(128, 0, 128, 1)">1</span>] = GetULongByBe(key, <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">);
MK[</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = GetULongByBe(key, <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">);
MK[</span><span style="color: rgba(128, 0, 128, 1)">3</span>] = GetULongByBe(key, <span style="color: rgba(128, 0, 128, 1)">12</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">long</span>[] k = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">long</span>[<span style="color: rgba(128, 0, 128, 1)">36</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">轮密钥生成方法</span>
k[<span style="color: rgba(128, 0, 128, 1)">0</span>] = MK[<span style="color: rgba(128, 0, 128, 1)">0</span>] ^ (<span style="color: rgba(0, 0, 255, 1)">long</span>)FK[<span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">];
k[</span><span style="color: rgba(128, 0, 128, 1)">1</span>] = MK[<span style="color: rgba(128, 0, 128, 1)">1</span>] ^ (<span style="color: rgba(0, 0, 255, 1)">long</span>)FK[<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">];
k[</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = MK[<span style="color: rgba(128, 0, 128, 1)">2</span>] ^ (<span style="color: rgba(0, 0, 255, 1)">long</span>)FK[<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">];
k[</span><span style="color: rgba(128, 0, 128, 1)">3</span>] = MK[<span style="color: rgba(128, 0, 128, 1)">3</span>] ^ (<span style="color: rgba(0, 0, 255, 1)">long</span>)FK[<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (; i < <span style="color: rgba(128, 0, 128, 1)">32</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
k[(i </span>+ <span style="color: rgba(128, 0, 128, 1)">4</span>)] = (k ^ Sm4CalciRk(k[(i + <span style="color: rgba(128, 0, 128, 1)">1</span>)] ^ k[(i + <span style="color: rgba(128, 0, 128, 1)">2</span>)] ^ k[(i + <span style="color: rgba(128, 0, 128, 1)">3</span>)] ^ (<span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)">)CK));
SK </span>= k[(i + <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">)];
}
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 解密函数
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="sk"></span><span style="color: rgba(0, 128, 0, 1)">轮密钥</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="input"></span><span style="color: rgba(0, 128, 0, 1)">输入分组的密文</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="output"></span><span style="color: rgba(0, 128, 0, 1)">输出的对应的分组明文</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Sm4OneRound(<span style="color: rgba(0, 0, 255, 1)">long</span>[] sk, <span style="color: rgba(0, 0, 255, 1)">byte</span>[] input, <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] output)
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">long</span>[] ulbuf = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">long</span>[<span style="color: rgba(128, 0, 128, 1)">36</span><span style="color: rgba(0, 0, 0, 1)">];
ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">0</span>] = GetULongByBe(input, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">1</span>] = GetULongByBe(input, <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">);
ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">2</span>] = GetULongByBe(input, <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">);
ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">3</span>] = GetULongByBe(input, <span style="color: rgba(128, 0, 128, 1)">12</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">while</span> (i < <span style="color: rgba(128, 0, 128, 1)">32</span>) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">开始32轮解密 ,一次进行4轮,共计八次</span>
<span style="color: rgba(0, 0, 0, 1)"> {
ulbuf[(i </span>+ <span style="color: rgba(128, 0, 128, 1)">4</span>)] = Sm4F(ulbuf, ulbuf[(i + <span style="color: rgba(128, 0, 128, 1)">1</span>)], ulbuf[(i + <span style="color: rgba(128, 0, 128, 1)">2</span>)], ulbuf[(i + <span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">)], sk);
i</span>++<span style="color: rgba(0, 0, 0, 1)">;
}
PutULongToBe(ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">35</span>], output, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
PutULongToBe(ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">34</span>], output, <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">);
PutULongToBe(ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">33</span>], output, <span style="color: rgba(128, 0, 128, 1)">8</span><span style="color: rgba(0, 0, 0, 1)">);
PutULongToBe(ulbuf[</span><span style="color: rgba(128, 0, 128, 1)">32</span>], output, <span style="color: rgba(128, 0, 128, 1)">12</span><span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 补足 16 进制字符串的 0 字符,返回不带 0x 的16进制字符串
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="input"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="mode"></span><span style="color: rgba(0, 128, 0, 1)">1表示加密,0表示解密</span><span style="color: rgba(128, 128, 128, 1)"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] Padding(<span style="color: rgba(0, 0, 255, 1)">byte</span>[] input, <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> mode)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (input == <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">;
}
</span><span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] ret;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (mode == <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> p = <span style="color: rgba(128, 0, 128, 1)">16</span> - input.Length % <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">;
ret </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>;
Array.Copy(input, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, ret, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, input.Length);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < p; i++<span style="color: rgba(0, 0, 0, 1)">)
{
ret = (<span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">)p;
}
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">int</span> p = input[^<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">];
ret </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>;
Array.Copy(input, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, ret, <span style="color: rgba(128, 0, 128, 1)">0</span>, input.Length -<span style="color: rgba(0, 0, 0, 1)"> p);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> ret;
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 设置加密的key
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="ctx"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="key"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> SetKeyEnc(Sm4Context ctx, <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] key)
{
ctx.Mode </span>= <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
SetKey(ctx.Key, key);
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 设置解密的key
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="ctx"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="key"></param></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> Sm4SetKeyDec(Sm4Context ctx, <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] key)
{
ctx.Mode </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">;
SetKey(ctx.Key, key);
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> i;
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < <span style="color: rgba(128, 0, 128, 1)">16</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
Swap(ctx.Key, i);
}
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> ECB
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="ctx"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="input"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] Sm4CryptEcb(Sm4Context ctx, <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] input)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx.IsPadding && (ctx.Mode == <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">))
{
input </span>= Padding(input, <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">int</span> length =<span style="color: rgba(0, 0, 0, 1)"> input.Length;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] bins = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">;
Array.Copy(input, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, bins, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, length);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] bous = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> i = <span style="color: rgba(128, 0, 128, 1)">0</span>; length > <span style="color: rgba(128, 0, 128, 1)">0</span>; length -= <span style="color: rgba(128, 0, 128, 1)">16</span>, i++<span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] inBytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] outBytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
Array.Copy(bins, i </span>* <span style="color: rgba(128, 0, 128, 1)">16</span>, inBytes, <span style="color: rgba(128, 0, 128, 1)">0</span>, length > <span style="color: rgba(128, 0, 128, 1)">16</span> ? <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)"> : length);
Sm4OneRound(ctx.Key, inBytes, outBytes);
Array.Copy(outBytes, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, bous, i * <span style="color: rgba(128, 0, 128, 1)">16</span>, length > <span style="color: rgba(128, 0, 128, 1)">16</span> ? <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)"> : length);
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx.IsPadding && ctx.Mode == <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
{
bous </span>= Padding(bous, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bous;
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> CBC
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="ctx"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="iv"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="input"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[] Sm4CryptCbc(Sm4Context ctx, <span style="color: rgba(0, 0, 255, 1)">byte</span>[] iv, <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">[] input)
{
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx.IsPadding && ctx.Mode == <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">)
{
input </span>= Padding(input, <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">);
}
</span><span style="color: rgba(0, 0, 255, 1)">int</span> length =<span style="color: rgba(0, 0, 0, 1)"> input.Length;
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] bins = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span><span style="color: rgba(0, 0, 0, 1)">;
Array.Copy(input, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, bins, <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">, length);
List</span><<span style="color: rgba(0, 0, 255, 1)">byte</span>> bousList = <span style="color: rgba(0, 0, 255, 1)">new</span> List<<span style="color: rgba(0, 0, 255, 1)">byte</span>><span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> i;
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx.Mode == <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> j = <span style="color: rgba(128, 0, 128, 1)">0</span>; length > <span style="color: rgba(128, 0, 128, 1)">0</span>; length -= <span style="color: rgba(128, 0, 128, 1)">16</span>, j++<span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] inBytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] outBytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] out1 = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
Array.Copy(bins, j </span>* <span style="color: rgba(128, 0, 128, 1)">16</span>, inBytes, <span style="color: rgba(128, 0, 128, 1)">0</span>, length > <span style="color: rgba(128, 0, 128, 1)">16</span> ? <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)"> : length);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < <span style="color: rgba(128, 0, 128, 1)">16</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
outBytes </span>= ((<span style="color: rgba(0, 0, 255, 1)">byte</span>)(inBytes ^<span style="color: rgba(0, 0, 0, 1)"> iv));
}
Sm4OneRound(ctx.Key, outBytes, out1);
Array.Copy(out1, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, iv, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> k = <span style="color: rgba(128, 0, 128, 1)">0</span>; k < <span style="color: rgba(128, 0, 128, 1)">16</span>; k++<span style="color: rgba(0, 0, 0, 1)">)
{
bousList.Add(out1);
}
}
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] temp = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> j = <span style="color: rgba(128, 0, 128, 1)">0</span>; length > <span style="color: rgba(128, 0, 128, 1)">0</span>; length -= <span style="color: rgba(128, 0, 128, 1)">16</span>, j++<span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] inBytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] outBytes = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] out1 = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">byte</span>[<span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">];
Array.Copy(bins, j </span>* <span style="color: rgba(128, 0, 128, 1)">16</span>, inBytes, <span style="color: rgba(128, 0, 128, 1)">0</span>, length > <span style="color: rgba(128, 0, 128, 1)">16</span> ? <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)"> : length);
Array.Copy(inBytes, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, temp, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
Sm4OneRound(ctx.Key, inBytes, outBytes);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (i = <span style="color: rgba(128, 0, 128, 1)">0</span>; i < <span style="color: rgba(128, 0, 128, 1)">16</span>; i++<span style="color: rgba(0, 0, 0, 1)">)
{
out1 </span>= ((<span style="color: rgba(0, 0, 255, 1)">byte</span>)(outBytes ^<span style="color: rgba(0, 0, 0, 1)"> iv));
}
Array.Copy(temp, </span><span style="color: rgba(128, 0, 128, 1)">0</span>, iv, <span style="color: rgba(128, 0, 128, 1)">0</span>, <span style="color: rgba(128, 0, 128, 1)">16</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">for</span> (<span style="color: rgba(0, 0, 255, 1)">int</span> k = <span style="color: rgba(128, 0, 128, 1)">0</span>; k < <span style="color: rgba(128, 0, 128, 1)">16</span>; k++<span style="color: rgba(0, 0, 0, 1)">)
{
bousList.Add(out1);
}
}
}
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (ctx.IsPadding && ctx.Mode == <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
{
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] bous = Padding(bousList.ToArray(), <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bous;
}
</span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> bousList.ToArray();
}
}
}</span></pre>
</div>
<p>1.2 SM4处理中心</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">internal</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Sm4Context
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Sm4Context()
{
Mode </span>= <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">;
IsPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
Key </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">long</span>[<span style="color: rgba(128, 0, 128, 1)">32</span><span style="color: rgba(0, 0, 0, 1)">];
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 1表示加密,0表示解密
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> Mode;
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 密钥
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)">[] Key;
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 是否补足16进制字符串
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> IsPadding;
}</span></pre>
</div>
<p>1.3调用</p>
<div class="cnblogs_code">
<pre> <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> Sm4算法
</span><span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 对标国际DES算法
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Sm4Crypto
{
</span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Sm4Crypto()
{
Key </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">98145489617106616498</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
Iv </span>= <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">0000000000000000</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
HexString </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
CryptoMode </span>=<span style="color: rgba(0, 0, 0, 1)"> Sm4CryptoEnum.ECB;
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 数据
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">string</span> Data { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 秘钥
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">string</span> Key { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 向量
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">string</span> Iv { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 明文是否是十六进制
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> HexString { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 加密模式(默认ECB)
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> Sm4CryptoEnum CryptoMode { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }
</span><span style="color: rgba(0, 0, 255, 1)">#region</span> 加密
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> Encrypt(Sm4Crypto entity)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> entity.CryptoMode == Sm4CryptoEnum.CBC ?<span style="color: rgba(0, 0, 0, 1)"> EncryptCBC(entity) : EncryptECB(entity);
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> ECB加密
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="entity"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> EncryptECB(Sm4Crypto entity)
{
Sm4Context ctx </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Sm4Context
{
IsPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
};
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] keyBytes = entity.HexString ?<span style="color: rgba(0, 0, 0, 1)"> Hex.Decode(entity.Key) : Encoding.Default.GetBytes(entity.Key);
SM4 sm4 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
sm4.SetKeyEnc(ctx, keyBytes);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] encrypted =<span style="color: rgba(0, 0, 0, 1)"> sm4.Sm4CryptEcb(ctx, Encoding.Default.GetBytes(entity.Data));
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetString(Hex.Encode(encrypted));
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> CBC加密
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="entity"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> EncryptCBC(Sm4Crypto entity)
{
Sm4Context ctx </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Sm4Context
{
IsPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">
};
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] keyBytes = entity.HexString ?<span style="color: rgba(0, 0, 0, 1)"> Hex.Decode(entity.Key) : Encoding.Default.GetBytes(entity.Key);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] ivBytes = entity.HexString ?<span style="color: rgba(0, 0, 0, 1)"> Hex.Decode(entity.Iv) : Encoding.Default.GetBytes(entity.Iv);
SM4 sm4 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
sm4.SetKeyEnc(ctx, keyBytes);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] encrypted =<span style="color: rgba(0, 0, 0, 1)"> sm4.Sm4CryptCbc(ctx, ivBytes, Encoding.Default.GetBytes(entity.Data));
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> encrypted.ToBase64();
}
</span><span style="color: rgba(0, 0, 255, 1)">#endregion</span>
<span style="color: rgba(0, 0, 255, 1)">#region</span> 解密
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> Decrypt(Sm4Crypto entity)
{
</span><span style="color: rgba(0, 0, 255, 1)">return</span> entity.CryptoMode == Sm4CryptoEnum.CBC ?<span style="color: rgba(0, 0, 0, 1)"> DecryptCBC(entity) : DecryptECB(entity);
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)">ECB解密
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="entity"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> DecryptECB(Sm4Crypto entity)
{
Sm4Context ctx </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Sm4Context
{
IsPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
Mode </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">
};
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] keyBytes = entity.HexString ?<span style="color: rgba(0, 0, 0, 1)"> Hex.Decode(entity.Key) : Encoding.Default.GetBytes(entity.Key);
SM4 sm4 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
sm4.Sm4SetKeyDec(ctx, keyBytes);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] decrypted =<span style="color: rgba(0, 0, 0, 1)"> sm4.Sm4CryptEcb(ctx, Hex.Decode(entity.Data));
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetString(decrypted);
}
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> CBC解密
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><param name="cipherText"></param></span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><returns></returns></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">string</span><span style="color: rgba(0, 0, 0, 1)"> DecryptCBC(Sm4Crypto entity)
{
Sm4Context ctx </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Sm4Context
{
IsPadding </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
Mode </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">
};
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] keyBytes = entity.HexString ?<span style="color: rgba(0, 0, 0, 1)"> Hex.Decode(entity.Key) : Encoding.Default.GetBytes(entity.Key);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] ivBytes = entity.HexString ?<span style="color: rgba(0, 0, 0, 1)"> Hex.Decode(entity.Iv) : Encoding.Default.GetBytes(entity.Iv);
SM4 sm4 </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> SM4();
sm4.Sm4SetKeyDec(ctx, keyBytes);
</span><span style="color: rgba(0, 0, 255, 1)">byte</span>[] decrypted =<span style="color: rgba(0, 0, 0, 1)"> sm4.Sm4CryptCbc(ctx, ivBytes, Convert.FromBase64String(entity.Data));
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> Encoding.Default.GetString(decrypted);
}
</span><span style="color: rgba(0, 0, 255, 1)">#endregion</span>
<span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 加密类型
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">enum</span><span style="color: rgba(0, 0, 0, 1)"> Sm4CryptoEnum
{
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> ECB(电码本模式)
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
ECB </span>= <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">,
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"><summary></span>
<span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> CBC(密码分组链接模式)
</span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)"></summary></span>
CBC </span>= <span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">
}
}</span></pre>
</div>
<p>1.4 所有类涉及的引用</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> Org.BouncyCastle.Utilities.Encoders;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.Collections.Generic;
</span><span style="color: rgba(0, 0, 255, 1)">using</span><span style="color: rgba(0, 0, 0, 1)"> System.ComponentModel;
</span><span style="color: rgba(0, 0, 255, 1)">using</span> System.Text;</pre>
</div>
<p> </p><br><br>
来源:https://www.cnblogs.com/raniynight/p/14077878.html
頁:
[1]