.Net Core關於SM4 加密算法

 國密SM4算法

與DES和AES算法相似,國密SM4算法是一種分組加密算法。SM4分組密碼算法是一種迭代分組密碼算法,由加解密算法和密鑰擴展算法組成。

SM4是一種Feistel結構的分組密碼算法,其分組長度和密鑰長度均爲128bits。加密算法和密鑰擴展算法迭代輪數均爲32輪。SM4加解密過程的算法相同但是輪密鑰的使用順序相反。

SM4密碼算法使用模2加和循環移位作爲基本運算。

密鑰擴展算法:SM4算法使用128位的加密密鑰,並採用32輪迭代加密結構,每一輪加密使用一個32位的輪密鑰,總共使用32個輪密鑰。因此需要使用密鑰擴展算法,從加密密鑰中產生32個輪密鑰。

SM4加解密流程

SM4算法的加密大致流程如下:

密鑰:加密密鑰的長度爲128比特,表示爲MK = (MK0, MK1, MK2, MK3),其中MKi爲32位,輪密鑰表示爲(rk0, rk1, ……, rk31),其中rki爲32位。

輪函數F:假設輸入爲(X0, X1, X2, X3),X爲32位,則輪函數F爲:F=(X0, X1, X2, X3, rk) = X0 ⊕ T(X1 ⊕ X2 ⊕ X3 ⊕ rk)

合成置換:T函數是一個可逆變換,由一個非線性變換r和線性變換L複合而成的,即T( )=L(r( ))

非線性變換有四個並行的S盒構成的,設輸入爲A=(a0, a1, a2, a3),輸出爲B=(b0, b1, b2, b3),其中ai和bi爲8位。每個S盒的輸入都是一個8位的字節,將這8位的前四位對應的16進制數作爲行編號,後四位對應的16進制數作爲列編號,然後用相應位置中的字節代替輸入的字節。下圖爲S盒置換表:

 

線性變換L:線形變換的輸入就是S盒的輸出,即C=L(B)=B ⊕ (B<<<2) ⊕ (B<<<10) ⊕ (B<<<18) ⊕ (B<<<24),線性變換的輸入和輸出都是32位的。

經過了32輪的迭代運算後,最後再進行一次反序變換即可得到加密的密文,即密文C=(Y0, Y1, Y2, Y3)=R(X32. X33, X34, X35)=(X35, X34, X33, X32)。

SM4算法的解密流程和加密流程一致,只不過輪密鑰的使用順序變成了(rk31, rk30, ……, rk0)

密鑰擴展算法

密鑰參量:輪密鑰由加密密鑰生成。FK=(FK0, FK1, FK2, FK3)爲系統參數,以及固定參數CK=(CK0, CK1, ……,  CK31),其中FKi和CKi均爲32位並用於密鑰擴展算法。

系統參數FK的具體取值如下:

FK0=(A3B1BAC6), FK1=(56AA3350), FK2=(677D9197), FK3=(B27022DC)

固定參數CK的具體取值如下:

密鑰擴展方法:設(K0, K1, K2, K3)=(MK0⊕FK0, MK1⊕FK1, MK2⊕FK2, MK3⊕FK3)

則rki=Ki+4=Ki⊕T‘(Ki+1⊕Ki+2⊕Ki+3⊕CKi)

其中T’()是將原來的T()中的線形變換L()替換成L'(B)=B⊕(B<<<13)⊕(B<<<23)

 

廢話不多說直接上代碼

  1 using Org.BouncyCastle.Utilities.Encoders;
  2 using System;
  3 using System.Collections.Generic;
  4 using System.Text;
  5 
  6 namespace SM
  7 {
  8 
  9     public class MainSm4
 10     {
 11         /// <summary>
 12         /// 加密ECB模式
 13         /// </summary>
 14         /// <param name="secretKey">密鑰</param>
 15         /// <param name="hexstring">明文是否是十六進制</param>
 16         /// <param name="plainText">明文</param>
 17         /// <returns>返回密文</returns>
 18         public string EncryptECB(string secretKey, bool hexstring, string plainText)
 19         {
 20             Sm4Context ctx = new Sm4Context();
 21             ctx.isPadding = true;
 22             ctx.mode = Sm4.SM4_ENCRYPT;
 23             byte[] keyBytes;
 24             if (hexstring)
 25             {
 26                 keyBytes = Hex.Decode(secretKey);
 27             }
 28             else
 29             {
 30                 keyBytes = Encoding.Default.GetBytes(secretKey);
 31             }
 32             Sm4 sm4 = new Sm4();
 33             sm4.sm4_setkey_enc(ctx, keyBytes);
 34 
 35             byte[] contentBytes = Encoding.Default.GetBytes(plainText);
 36 
 37             byte[] encrypted = sm4.sm4_crypt_ecb(ctx, contentBytes);
 38 
 39             string cipherText = Convert.ToBase64String(encrypted);
 40 
 41             //byte[] encrypted = sm4.sm4_crypt_ecb(ctx, Encoding.Default.GetBytes(plainText));
 42             //string cipherText = Encoding.Default.GetString(Hex.Encode(encrypted));
 43             return cipherText;
 44         }
 45 
 46         /// <summary>
 47         /// 解密ECB模式
 48         /// </summary>
 49         /// <param name="secretKey">密鑰</param>
 50         /// <param name="hexstring">明文是否是十六進制</param>
 51         /// <param name="cipherText">密文</param>
 52         /// <returns>返回明文</returns>
 53         public string DecryptECB(string secretKey, bool hexstring, string cipherText)
 54         {
 55             Sm4Context ctx = new Sm4Context();
 56             ctx.isPadding = true;
 57             ctx.mode = Sm4.SM4_DECRYPT;
 58 
 59             byte[] keyBytes;
 60             if (hexstring)
 61             {
 62                 keyBytes = Hex.Decode(secretKey);
 63             }
 64             else
 65             {
 66                 keyBytes = Encoding.Default.GetBytes(secretKey);
 67             }
 68 
 69             Sm4 sm4 = new Sm4();
 70             sm4.sm4_setkey_dec(ctx, keyBytes);
 71 
 72             byte[] contentBytes = Convert.FromBase64String(cipherText);
 73 
 74             byte[] decrypted = sm4.sm4_crypt_ecb(ctx, contentBytes);
 75 
 76             //byte[] decrypted = sm4.sm4_crypt_ecb(ctx, Hex.Decode(cipherText));
 77             return Encoding.Default.GetString(decrypted);
 78         }
 79 
 80         /// <summary>
 81         /// 加密CBC模式
 82         /// </summary>
 83         /// <param name="secretKey">密鑰</param>
 84         /// <param name="hexstring">明文是否是十六進制</param>
 85         /// <param name="iv"></param>
 86         /// <param name="plainText">明文</param>
 87         /// <returns>返回密文</returns>
 88         public string EncryptCBC(string secretKey, bool hexstring, string iv, string plainText)
 89         {
 90             Sm4Context ctx = new Sm4Context();
 91             ctx.isPadding = true;
 92             ctx.mode = Sm4.SM4_ENCRYPT;
 93             byte[] keyBytes;
 94             byte[] ivBytes;
 95             if (hexstring)
 96             {
 97                 keyBytes = Hex.Decode(secretKey);
 98                 ivBytes = Hex.Decode(iv);
 99             }
100             else
101             {
102                 keyBytes = Encoding.Default.GetBytes(secretKey);
103                 ivBytes = Encoding.Default.GetBytes(iv);
104             }
105             Sm4 sm4 = new Sm4();
106             sm4.sm4_setkey_enc(ctx, keyBytes);
107             byte[] encrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Encoding.Default.GetBytes(plainText));
108             string cipherText = Encoding.Default.GetString(Hex.Encode(encrypted));
109             return cipherText;
110         }
111 
112         /// <summary>
113         /// 解密CBC模式
114         /// </summary>
115         /// <param name="secretKey">密鑰</param>
116         /// <param name="hexstring">明文是否是十六進制</param>
117         /// <param name="iv"></param>
118         /// <param name="cipherText">密文</param>
119         /// <returns>返回明文</returns>
120         public string DecryptCBC(string secretKey, bool hexstring, string iv, string cipherText)
121         {
122             Sm4Context ctx = new Sm4Context();
123             ctx.isPadding = true;
124             ctx.mode = Sm4.SM4_DECRYPT;
125             byte[] keyBytes;
126             byte[] ivBytes;
127             if (hexstring)
128             {
129                 keyBytes = Hex.Decode(secretKey);
130                 ivBytes = Hex.Decode(iv);
131             }
132             else
133             {
134                 keyBytes = Encoding.Default.GetBytes(secretKey);
135                 ivBytes = Encoding.Default.GetBytes(iv);
136             }
137             Sm4 sm4 = new Sm4();
138             sm4.sm4_setkey_dec(ctx, keyBytes);
139             byte[] decrypted = sm4.sm4_crypt_cbc(ctx, ivBytes, Hex.Decode(cipherText));
140             return Encoding.Default.GetString(decrypted);
141         }
142     }
143 
144 
145     public class Sm4
146     {
147         public const int SM4_ENCRYPT = 1;
148         public const int SM4_DECRYPT = 0;
149 
150         private long GET_ULONG_BE(byte[] b, int i)
151         {
152             long n = (long)(b[i] & 0xff) << 24 | (long)((b[i + 1] & 0xff) << 16) | (long)((b[i + 2] & 0xff) << 8) | (long)(b[i + 3] & 0xff) & 0xffffffffL;
153             return n;
154         }
155         private void PUT_ULONG_BE(long n, byte[] b, int i)
156         {
157             b[i] = (byte)(int)(0xFF & n >> 24);
158             b[i + 1] = (byte)(int)(0xFF & n >> 16);
159             b[i + 2] = (byte)(int)(0xFF & n >> 8);
160             b[i + 3] = (byte)(int)(0xFF & n);
161         }
162         private long SHL(long x, int n)
163         {
164             return (x & 0xFFFFFFFF) << n;
165         }
166 
167         private long ROTL(long x, int n)
168         {
169             return SHL(x, n) | x >> (32 - n);
170         }
171 
172         private void SWAP(long[] sk, int i)
173         {
174             long t = sk[i];
175             sk[i] = sk[(31 - i)];
176             sk[(31 - i)] = t;
177         }
178 
179         public byte[] SboxTable = new byte[] { (byte) 0xd6, (byte) 0x90, (byte) 0xe9, (byte) 0xfe,
180         (byte) 0xcc, (byte) 0xe1, 0x3d, (byte) 0xb7, 0x16, (byte) 0xb6,
181         0x14, (byte) 0xc2, 0x28, (byte) 0xfb, 0x2c, 0x05, 0x2b, 0x67,
182         (byte) 0x9a, 0x76, 0x2a, (byte) 0xbe, 0x04, (byte) 0xc3,
183         (byte) 0xaa, 0x44, 0x13, 0x26, 0x49, (byte) 0x86, 0x06,
184         (byte) 0x99, (byte) 0x9c, 0x42, 0x50, (byte) 0xf4, (byte) 0x91,
185         (byte) 0xef, (byte) 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43,
186         (byte) 0xed, (byte) 0xcf, (byte) 0xac, 0x62, (byte) 0xe4,
187         (byte) 0xb3, 0x1c, (byte) 0xa9, (byte) 0xc9, 0x08, (byte) 0xe8,
188         (byte) 0x95, (byte) 0x80, (byte) 0xdf, (byte) 0x94, (byte) 0xfa,
189         0x75, (byte) 0x8f, 0x3f, (byte) 0xa6, 0x47, 0x07, (byte) 0xa7,
190         (byte) 0xfc, (byte) 0xf3, 0x73, 0x17, (byte) 0xba, (byte) 0x83,
191         0x59, 0x3c, 0x19, (byte) 0xe6, (byte) 0x85, 0x4f, (byte) 0xa8,
192         0x68, 0x6b, (byte) 0x81, (byte) 0xb2, 0x71, 0x64, (byte) 0xda,
193         (byte) 0x8b, (byte) 0xf8, (byte) 0xeb, 0x0f, 0x4b, 0x70, 0x56,
194         (byte) 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, (byte) 0xd1,
195         (byte) 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, (byte) 0x87,
196         (byte) 0xd4, 0x00, 0x46, 0x57, (byte) 0x9f, (byte) 0xd3, 0x27,
197         0x52, 0x4c, 0x36, 0x02, (byte) 0xe7, (byte) 0xa0, (byte) 0xc4,
198         (byte) 0xc8, (byte) 0x9e, (byte) 0xea, (byte) 0xbf, (byte) 0x8a,
199         (byte) 0xd2, 0x40, (byte) 0xc7, 0x38, (byte) 0xb5, (byte) 0xa3,
200         (byte) 0xf7, (byte) 0xf2, (byte) 0xce, (byte) 0xf9, 0x61, 0x15,
201         (byte) 0xa1, (byte) 0xe0, (byte) 0xae, 0x5d, (byte) 0xa4,
202         (byte) 0x9b, 0x34, 0x1a, 0x55, (byte) 0xad, (byte) 0x93, 0x32,
203         0x30, (byte) 0xf5, (byte) 0x8c, (byte) 0xb1, (byte) 0xe3, 0x1d,
204         (byte) 0xf6, (byte) 0xe2, 0x2e, (byte) 0x82, 0x66, (byte) 0xca,
205         0x60, (byte) 0xc0, 0x29, 0x23, (byte) 0xab, 0x0d, 0x53, 0x4e, 0x6f,
206         (byte) 0xd5, (byte) 0xdb, 0x37, 0x45, (byte) 0xde, (byte) 0xfd,
207         (byte) 0x8e, 0x2f, 0x03, (byte) 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b,
208         0x51, (byte) 0x8d, 0x1b, (byte) 0xaf, (byte) 0x92, (byte) 0xbb,
209         (byte) 0xdd, (byte) 0xbc, 0x7f, 0x11, (byte) 0xd9, 0x5c, 0x41,
210         0x1f, 0x10, 0x5a, (byte) 0xd8, 0x0a, (byte) 0xc1, 0x31,
211         (byte) 0x88, (byte) 0xa5, (byte) 0xcd, 0x7b, (byte) 0xbd, 0x2d,
212         0x74, (byte) 0xd0, 0x12, (byte) 0xb8, (byte) 0xe5, (byte) 0xb4,
213         (byte) 0xb0, (byte) 0x89, 0x69, (byte) 0x97, 0x4a, 0x0c,
214         (byte) 0x96, 0x77, 0x7e, 0x65, (byte) 0xb9, (byte) 0xf1, 0x09,
215         (byte) 0xc5, 0x6e, (byte) 0xc6, (byte) 0x84, 0x18, (byte) 0xf0,
216         0x7d, (byte) 0xec, 0x3a, (byte) 0xdc, 0x4d, 0x20, 0x79,
217         (byte) 0xee, 0x5f, 0x3e, (byte) 0xd7, (byte) 0xcb, 0x39, 0x48 };
218         public uint[] FK = { 0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc };
219         public uint[] CK = { 0x00070e15,0x1c232a31,0x383f464d,0x545b6269,
220                                     0x70777e85,0x8c939aa1,0xa8afb6bd,0xc4cbd2d9,
221                                     0xe0e7eef5,0xfc030a11,0x181f262d,0x343b4249,
222                                     0x50575e65,0x6c737a81,0x888f969d,0xa4abb2b9,
223                                     0xc0c7ced5,0xdce3eaf1,0xf8ff060d,0x141b2229,
224                                     0x30373e45,0x4c535a61,0x686f767d,0x848b9299,
225                                     0xa0a7aeb5,0xbcc3cad1,0xd8dfe6ed,0xf4fb0209,
226                                     0x10171e25,0x2c333a41,0x484f565d,0x646b7279 };
227         private byte sm4Sbox(byte inch)
228         {
229             int i = inch & 0xFF;
230             byte retVal = SboxTable[i];
231             return retVal;
232         }
233         private long sm4Lt(long ka)
234         {
235             long bb = 0L;
236             long c = 0L;
237             byte[] a = new byte[4];
238             byte[] b = new byte[4];
239             PUT_ULONG_BE(ka, a, 0);
240             b[0] = sm4Sbox(a[0]);
241             b[1] = sm4Sbox(a[1]);
242             b[2] = sm4Sbox(a[2]);
243             b[3] = sm4Sbox(a[3]);
244             bb = GET_ULONG_BE(b, 0);
245             c = bb ^ ROTL(bb, 2) ^ ROTL(bb, 10) ^ ROTL(bb, 18) ^ ROTL(bb, 24);
246             return c;
247         }
248         private long sm4F(long x0, long x1, long x2, long x3, long rk)
249         {
250             return x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk);
251         }
252 
253         private long sm4CalciRK(long ka)
254         {
255             long bb = 0L;
256             long rk = 0L;
257             byte[] a = new byte[4];
258             byte[] b = new byte[4];
259             PUT_ULONG_BE(ka, a, 0);
260             b[0] = sm4Sbox(a[0]);
261             b[1] = sm4Sbox(a[1]);
262             b[2] = sm4Sbox(a[2]);
263             b[3] = sm4Sbox(a[3]);
264             bb = GET_ULONG_BE(b, 0);
265             rk = bb ^ ROTL(bb, 13) ^ ROTL(bb, 23);
266             return rk;
267         }
268 
269         private void sm4_setkey(long[] SK, byte[] key)
270         {
271             long[] MK = new long[4];
272             long[] k = new long[36];
273             int i = 0;
274             MK[0] = GET_ULONG_BE(key, 0);
275             MK[1] = GET_ULONG_BE(key, 4);
276             MK[2] = GET_ULONG_BE(key, 8);
277             MK[3] = GET_ULONG_BE(key, 12);
278             k[0] = MK[0] ^ (long)FK[0];
279             k[1] = MK[1] ^ (long)FK[1];
280             k[2] = MK[2] ^ (long)FK[2];
281             k[3] = MK[3] ^ (long)FK[3];
282             for (; i < 32; i++)
283             {
284                 k[(i + 4)] = (k[i] ^ sm4CalciRK(k[(i + 1)] ^ k[(i + 2)] ^ k[(i + 3)] ^ (long)CK[i]));
285                 SK[i] = k[(i + 4)];
286             }
287         }
288 
289         private void sm4_one_round(long[] sk, byte[] input, byte[] output)
290         {
291             int i = 0;
292             long[] ulbuf = new long[36];
293             ulbuf[0] = GET_ULONG_BE(input, 0);
294             ulbuf[1] = GET_ULONG_BE(input, 4);
295             ulbuf[2] = GET_ULONG_BE(input, 8);
296             ulbuf[3] = GET_ULONG_BE(input, 12);
297             while (i < 32)
298             {
299                 ulbuf[(i + 4)] = sm4F(ulbuf[i], ulbuf[(i + 1)], ulbuf[(i + 2)], ulbuf[(i + 3)], sk[i]);
300                 i++;
301             }
302             PUT_ULONG_BE(ulbuf[35], output, 0);
303             PUT_ULONG_BE(ulbuf[34], output, 4);
304             PUT_ULONG_BE(ulbuf[33], output, 8);
305             PUT_ULONG_BE(ulbuf[32], output, 12);
306         }
307 
308         private byte[] padding(byte[] input, int mode)
309         {
310             if (input == null)
311             {
312                 return null;
313             }
314 
315             byte[] ret = (byte[])null;
316             if (mode == SM4_ENCRYPT)
317             {
318                 int p = 16 - input.Length % 16;
319                 ret = new byte[input.Length + p];
320                 Array.Copy(input, 0, ret, 0, input.Length);
321                 for (int i = 0; i < p; i++)
322                 {
323                     ret[input.Length + i] = (byte)p;
324                 }
325             }
326             else
327             {
328                 int p = input[input.Length - 1];
329                 ret = new byte[input.Length - p];
330                 Array.Copy(input, 0, ret, 0, input.Length - p);
331             }
332             return ret;
333         }
334 
335         public void sm4_setkey_enc(Sm4Context ctx, byte[] key)
336         {
337             ctx.mode = SM4_ENCRYPT;
338             sm4_setkey(ctx.sk, key);
339         }
340 
341         public void sm4_setkey_dec(Sm4Context ctx, byte[] key)
342         {
343             int i = 0;
344             ctx.mode = SM4_DECRYPT;
345             sm4_setkey(ctx.sk, key);
346             for (i = 0; i < 16; i++)
347             {
348                 SWAP(ctx.sk, i);
349             }
350         }
351 
352         public byte[] sm4_crypt_ecb(Sm4Context ctx, byte[] input)
353         {
354             if ((ctx.isPadding) && (ctx.mode == SM4_ENCRYPT))
355             {
356                 input = padding(input, SM4_ENCRYPT);
357             }
358 
359             int length = input.Length;
360             byte[] bins = new byte[length];
361             Array.Copy(input, 0, bins, 0, length);
362             byte[] bous = new byte[length];
363             for (int i = 0; length > 0; length -= 16, i++)
364             {
365                 byte[] inBytes = new byte[16];
366                 byte[] outBytes = new byte[16];
367                 Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length);
368                 sm4_one_round(ctx.sk, inBytes, outBytes);
369                 Array.Copy(outBytes, 0, bous, i * 16, length > 16 ? 16 : length);
370             }
371 
372             if (ctx.isPadding && ctx.mode == SM4_DECRYPT)
373             {
374                 bous = padding(bous, SM4_DECRYPT);
375             }
376             return bous;
377         }
378 
379         public byte[] sm4_crypt_cbc(Sm4Context ctx, byte[] iv, byte[] input)
380         {
381             if (ctx.isPadding && ctx.mode == SM4_ENCRYPT)
382             {
383                 input = padding(input, SM4_ENCRYPT);
384             }
385 
386             int i = 0;
387             int length = input.Length;
388             byte[] bins = new byte[length];
389             Array.Copy(input, 0, bins, 0, length);
390             byte[] bous = null;
391             List<byte> bousList = new List<byte>();
392             if (ctx.mode == SM4_ENCRYPT)
393             {
394                 for (int j = 0; length > 0; length -= 16, j++)
395                 {
396                     byte[] inBytes = new byte[16];
397                     byte[] outBytes = new byte[16];
398                     byte[] out1 = new byte[16];
399                     Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length);
400                     for (i = 0; i < 16; i++)
401                     {
402                         outBytes[i] = ((byte)(inBytes[i] ^ iv[i]));
403                     }
404                     sm4_one_round(ctx.sk, outBytes, out1);
405                     Array.Copy(out1, 0, iv, 0, 16);
406                     for (int k = 0; k < 16; k++)
407                     {
408                         bousList.Add(out1[k]);
409                     }
410                 }
411             }
412             else
413             {
414                 byte[] temp = new byte[16];
415                 for (int j = 0; length > 0; length -= 16, j++)
416                 {
417                     byte[] inBytes = new byte[16];
418                     byte[] outBytes = new byte[16];
419                     byte[] out1 = new byte[16];
420 
421 
422                     Array.Copy(bins, i * 16, inBytes, 0, length > 16 ? 16 : length);
423                     Array.Copy(inBytes, 0, temp, 0, 16);
424                     sm4_one_round(ctx.sk, inBytes, outBytes);
425                     for (i = 0; i < 16; i++)
426                     {
427                         out1[i] = ((byte)(outBytes[i] ^ iv[i]));
428                     }
429                     Array.Copy(temp, 0, iv, 0, 16);
430                     for (int k = 0; k < 16; k++)
431                     {
432                         bousList.Add(out1[k]);
433                     }
434                 }
435             }
436 
437             if (ctx.isPadding && ctx.mode == SM4_DECRYPT)
438             {
439                 bous = padding(bousList.ToArray(), SM4_DECRYPT);
440                 return bous;
441             }
442             else
443             {
444                 return bousList.ToArray();
445             }
446         }
447     }
448 
449     public class Sm4Context
450     {
451         public int mode;
452         public long[] sk;
453         public bool isPadding;
454         public Sm4Context()
455         {
456             this.mode = 1;
457             this.isPadding = true;
458             this.sk = new long[32];
459         }
460     }
461 }

 

 

 1 using System;
 2 using System.Collections.Generic;
 3 using System.IO;
 4 using System.Security.Cryptography;
 5 using System.Text;
 6 
 7 namespace SM
 8 {
 9 
10     public class SignUtil
11     {
12 
13         public static string EncryptData(string appSecret, string data)
14         {
15             var sm4 = new MainSm4();
16 
17             return sm4.EncryptECB(appSecret, true, data);
18         }
19 
20         public static string DecryptData(string appSecret, string data)
21         {
22             var sm4 = new MainSm4();
23             return sm4.DecryptECB(appSecret, true, data);
24         }
25 
26         public static string MarkSign(string signType, Dictionary<string, string> paramDic)
27         {
28             if (paramDic == null || paramDic.Count == 0)
29             {
30                 throw new Exception("簽名參數不能爲空");
31             }
32 
33             StringBuilder sbStr = new StringBuilder();
34             foreach (var param in paramDic)
35             {
36                 sbStr.Append(param.Value);
37             }
38 
39             string beforeSignStr = sbStr.Append(signType).ToString();
40 
41             if (signType == "MD5")
42             {
43                 return Md5Hex(beforeSignStr);
44             }
45 
46             throw new Exception("未實現加密方式");
47         }
48 
49         private static string Md5Hex(string data)
50         {
51             MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
52             byte[] dataHash = md5.ComputeHash(Encoding.UTF8.GetBytes(data));
53             StringBuilder sb = new StringBuilder();
54             foreach (byte b in dataHash)
55             {
56                 sb.Append(b.ToString("x2").ToLower());
57             }
58             return sb.ToString();
59         }
60 
61         /**
62         * 生成時間戳,標準北京時間,時區爲東八區,自1970年1月1日 0點0分0秒以來的秒數
63          * @return 時間戳
64         */
65         public static string GenerateTimeStamp()
66         {
67             TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
68             return Convert.ToInt64(ts.TotalSeconds).ToString();
69         }
70     }
71 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章