国密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 }

关于SM4 加密算法的更多相关文章

  1. SM4加密算法实现Java和C#相互加密解密

    SM4加密算法实现Java和C#相互加密解密 近期由于项目需要使用SM4对数据进行加密,然后传给Java后台,Java后台使用的也是SM4的加密算法但是就是解密不正确,经过一步步调试发现Java中好多 ...

  2. 国密SM4分组加密算法实现 (C++)

    原博客 :http://blog.csdn.net/archimekai/article/details/53095993 密码学的一次课程设计,学习了SM4加密算法,目前应用于无线网安全. SM4分 ...

  3. 一文带你学会国产加密算法SM4的java实现方案

    前言 今天给大家带来一个国产SM4加密解密算法的java后端解决方案,代码完整,可以直接使用,希望给大家带来帮助,尤其是做政府系统的开发人员,可以直接应用到项目中进行加密解密. 画重点!是SM4哦,不 ...

  4. 一文带你学会国产加密算法SM4的vue实现方案

    前言 上篇文章我们介绍了国产SM4加密算法的后端java实现方案.没有看过的小伙伴可以看一下这篇文章. https://www.cnblogs.com/jichi/p/12907453.html 本篇 ...

  5. SM4密码算法(附源码)

    SM4是我们自己国家的一个分组密码算法,是国家密码管理局于2012年发布的.网址戳→_→:http://www.cnnic.NET.cn/jscx/mixbz/sm4/ 具体的密码标准和算法官方有非常 ...

  6. java sm4国密算法加密、解密

      java sm4国密算法加密.解密 CreationTime--2018年7月5日09点20分 Author:Marydon 1.准备工作 所需jar包: bcprov-jdk15on-1.59. ...

  7. 基于crypto++国产加密软件SM4的实现,顺带加了ase,base64

    唔,美国压制得越狠,各种替代产品就越能活. 本文分享SM4的一种快速实现与集成方式.             SM4(原名SMS4)是中华人民共和国政府采用的一种分组密码标准,由国家密码管理局于201 ...

  8. sm4算法(附源码、测试代码)

    from:http://blog.csdn.net/mao0514/article/details/52930944 SM4是我们自己国家的一个分组密码算法,是国家密码管理局于2012年发布的.网址戳 ...

  9. stm32——NFC芯片--PN532的使用

    stm32——NFC芯片--PN532的使用 一.NFC简介 NFC(Near Field Communication)近场通信,是一种短距高频的无线电技术,在13.56MHz频率运行于20厘米距离内 ...

随机推荐

  1. Bootstrap(修改中)

    表格 斑马表格 <table class="table-striped"> </table> 鼠标经过表格的hover效果 <table class= ...

  2. mongo聚合操作

    1 mongodb的聚合是什么 聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组.过滤等功能,然后经过一系列的处理, ...

  3. java并发编程实战《三》互斥锁(上)

    互斥锁(上):解决原子性问题 原子性问题的源头是线程切换,操作系统做线程切换是依赖 CPU 中断的,所以禁止 CPU 发生中断就能够禁止线程切换. 在早期单核 CPU 时代,这个方案的确是可行的,而且 ...

  4. PyQt(Python+Qt)学习随笔:QTableWidget的takeItem和sortItems方法

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 QTableWidget中的takeItem方法从表格中取并去除项,sortItems方法对表格中的 ...

  5. Python+Qt学习随笔:PyQt中常用的事件处理函数

    在PyQt图形界面中,我们经常要捕获特定事件如鼠标按键按下.鼠标按下等事件以执行特定操作,可以通过重写组件对象的相关事件处理函数来实现相关处理,具体特定事件常用的包括如下: keyPressEvent ...

  6. BUUOJ 杂项MISC(1)

    爱因斯坦 下载之后解压打开是一张爱因斯坦的图片,看来是图片隐写题 使用binwalk -e misc2.jpg 获得一个有flag.txt的压缩包,但是需要密码才能打开,猜想密码在图片里面,把图片丢进 ...

  7. kaggle——Bag of Words Meets Bags of Popcorn(IMDB电影评论情感分类实践)

    kaggle链接:https://www.kaggle.com/c/word2vec-nlp-tutorial/overview 简介:给出 50,000 IMDB movie reviews,进行0 ...

  8. 0、tensorflow学习开始

    结合tensorflowtf 2.x , tensorflow 1.x, pytorch来深入理解深度学习架构,用博客来记录这一系列,日后也方便回顾,博客中也会加入个人理解和感悟 参考的博客列表如下: ...

  9. python中的多线程和多进程

    一.简单理解一下线程和进程 一个进程中可有多个线程,线程之间可共享内存,进程间却是相互独立的.打比方就是,进程是火车,线程是火车厢,车厢内人员可以流动(数据共享) 二.python中的多线程和多进程 ...

  10. 影评网站Alpha版本-测试与发布

    影评网站Alpha版本-测试与发布 项目发布地址: http://120.78.161.21:8080/zhiying/ (建议使用Chrome或火狐浏览器打开,其他浏览器可能加载失败 一.Alpha ...