国密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. MacOS Big Sur11.0升级后Eclipse启动报错

    本次升级MacOS Big Sur11.0.1之后,开启Eclipse时报空指针,打开页面空白,之后卸掉, 再次安装时提示加载不到libserver.dylib 或 Could not create ...

  2. JZOJ【NOIP2013模拟联考14】隐藏指令

    JZOJ[NOIP2013模拟联考14]隐藏指令 题目 Description 在d维欧几里得空间中,指令是一个长度为2N的串.串的每一个元素为d个正交基的方向及反方向之一.例如,d = 1时(数轴) ...

  3. JZOJ8月6日提高组反思

    JZOJ8月6日提高组反思 又是愉快的没落的一天 被2020&2018暴打day2 一堆人AK-- T1 看到这个\(m\)只有100 就坚定了我打暴力的信心 离散化加暴力匹配 原本就想\(3 ...

  4. Linux之【安装系统后的调优和安全设置】

    关闭SElinux功能 •修改配置文件使其永远生效 第一种修改方法vi vi /etc/sysconfig/selinuc 或者 vi /etc/selinux/config修改: SELINUX=d ...

  5. linux离线安装docker + docker-compose

    1 准备阶段(docker) 1.1 卸载旧版本 如果电脑上已经存在docker,需要先卸载可能存在的旧版本: 1. 删除某软件,及其安装时自动安装的所有包 sudo apt-get autoremo ...

  6. 区块链学习7:超级账本项目Fabric中的背书、背书节点、背书策略、背书签名

    ☞ ░ 前往老猿Python博文目录 ░ 在Hyperledger Fabric区块链中,有背书节点进行背书,Hyperledger Fabric 使用背书策略来定义哪些节点需要执行交易. Hyper ...

  7. moviepy音视频开发:audio_fadein、fadeout实现声音淡入淡出

    ☞ ░ 前往老猿Python博文目录 ░ 一.概述 为了支持一些常规的音频变换处理,moviepy提供了一系列常用的变换函数,开发者可以直接使用这些方法进行变换,这些函数都在moviepy.audio ...

  8. 安装pyspider出现的问题

    本文来自微信公众号:coder_xiaobu,欢迎关注 一.安装pyspider pip install pyspider 二.启动 pyspider all 三.安装中出现的问题处理 安装的时候出现 ...

  9. 百度前端技术学院-基础-day1

    2020.9.14 今天我开始在百度前端技术学院学习基础课程. 先立一个Flag,希望我能在30天之内学完前四十天的课程,后续课程再一天一节. 第一天的内容主要是提供了很多基础学习的网页,比如W3sc ...

  10. MySQL日期和时间函数汇总

    本文基于MySQL8.0 本文介绍MySQL关于日期和时间操作的函数. 日期和时间函数 函数 描述 ADDDATE() 给日期值添加时间值 ADDTIME() 添加time CONVERT_TZ() ...