最新发现资源文件中sm2.c 654行(KDF函数中)的i++需要删除,现在CSDN付费资源不能修改,请下载的同学自行删除这行,十分抱歉!
     在网上搜过关于SM2/SM3的资源,很少有在单片机上实现的代码。主要是因为大数运算基本都用 Miracl/Openssl库,移植到嵌入式平台上很麻烦。所以索性自己动手写了一下Fp域(质数域)下的SM2算法实现(动态申请内存)。包括SM2算法三步曲——数字签名,秘钥交换和公钥加密,以及SM3哈希杂凑算法的实现。由于SM3算法比较简单,所以本文主要介绍SM2算法。本文所有代码参考国家密码管理局官方文档https://sca.gov.cn/sca/xwdt/2010-12/17/1002386/files/b791a9f908bb4803875ab6aeeb7b4e03.pdf 完整代码点这里。有任何问题可以私信联系。

1. 国密SM2介绍

SM2是国家密码管理局于2010年12月17日发布的椭圆曲线公钥密码算法。SM2算法和RSA算法都是公钥密码算法,SM2算法是一种更先进安全的算法,在我们国家商用密码体系中被用来替换RSA算法。SM2是ECC(Elliptic Curve Cryptosystem)算法的一种,基于椭圆曲线离散对数问题,计算复杂度是指数级,求解难度较大,同等安全程度要求下,椭圆曲线密码较其他公钥秒速昂发所需密钥长度小很多。
     随着密码技术和计算机技术的发展,目前常用的1024位RSA算法面临严重的安全威胁,我们国家密码管理部门经过研究,决定采用SM2椭圆曲线算法替换RSA算法。

2. SM2数字签名算法

数字签名算法由一个签名者对数据产生数字签名,并由一个验证者验证签名的可靠性。每个签名者有一个公钥和一个私钥,其中私钥用于产生签名,验证者用签名者的公钥验证签名。在签名的生成过程之前,要用密码杂凑函数对M‾\overline{M}M (包含ZA_AA​和待签消息M)进行压缩;在验证过程之前,要用密码杂凑函数对M‾\overline{M}M’(包含ZA_AA​和验证消息M′)进行压缩。

2.1 数字签名生成算法流程:

1.   SM2Signature* SM2Sign(char* message, int messageSizeInBit, char* IDA, uint16_t ENTLAInBit, EccPoint* G, EccPoint* pubKey, uint64_t* privKey)
2.  {
3.      //ZA = SM3(ENT LA ∥ IDA ∥ a ∥ b ∥ xG ∥ yG ∥ xA ∥ yA)。
4.      uint8_t* Z = malloc(2 + ENTLAInBit / 8 + 32 + 32 + 32 + 32 + 32 + 32), * ZA = malloc(32);
5.      uint256_t tmpN = { 0 };
6.      SM2Signature* result = malloc(sizeof(SM2Signature));
7.
8.      for (int i = 0; i < 4; i++)
9.      {
10.         tmpN[i] = ellipticCurve_n[3 - i];
11.     }
12.     Z[0] = ENTLAInBit >> 8;
13.     Z[1] = ENTLAInBit & 0xff;
14.     memcpy(Z + 2, IDA, ENTLAInBit / 8);
15.     Uint256ToString(ZA, Ec->a);
16.     memcpy(Z + 2 + ENTLAInBit / 8, ZA, 32);
17.     Uint256ToString(ZA, Ec->b);
18.     memcpy(Z + 2 + ENTLAInBit / 8 + 32, ZA, 32);
19.     Uint256ToString(ZA, G->x);
20.     memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 2, ZA, 32);
21.     Uint256ToString(ZA, G->y);
22.     memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 3, ZA, 32);
23.     Uint256ToString(ZA, pubKey->x);
24.     memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 4, ZA, 32);
25.     Uint256ToString(ZA, pubKey->y);
26.     memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 5, ZA, 32);
27.     SM3(Z, 2 + ENTLAInBit / 8 + 32 + 32 + 32 + 32 + 32 + 32, ZA);//ZA = SM3(ENT LA ∥ IDA ∥ a ∥ b ∥ xG ∥ yG ∥ xA ∥ yA)。
28.     free(Z);
29.
30.     uint8_t* M_ = malloc(messageSizeInBit / 8 + 32), * e = malloc(32);
31.     memcpy(M_, ZA, 32);
32.     memcpy(M_ + 32, message, messageSizeInBit / 8);
33.     SM3(M_, messageSizeInBit / 8 + 32, e);  //e = H256(M_):
34.     free(M_);
35.
36.     uint8_t* x1 = malloc(32), * y1 = malloc(32), * r = malloc(32), * s = malloc(32);
37.     uint256_t randomK = { 0 }, tmpE = { 0 }, tmpX = { 0 }, tmpR = { 0 }, num1 = { 1 };
38.     EccPoint* point1 = malloc(sizeof(EccPoint));
39.     GetRandomNumber(randomK, tmpN);
40. #ifdef DEBUG_MODE
41.     for (int i = 0; i < 4; i++)  //测试时随机数先固定
42.     {
43.         randomK[i] = exRandomK[3 - i];
44.     }
45. #endif
46.
47.     CurvePointMul(point1, G, randomK);
48.     Uint256ToString(x1, point1->x);
49.     Uint256ToString(y1, point1->y);
50.     free(point1);
51.     StringToUint256(tmpE, e);
52.     StringToUint256(tmpX, x1);
53.     vli_modAdd(tmpR, tmpE, tmpX, tmpN);
54.     Uint256ToString(r, tmpR);   //r=(e+x1) modn
55.
56.     vli_modAdd(tmpE, num1, privKey, tmpN);
57.     vli_modInv(tmpX, tmpE, tmpN);   //(1+dA)^-1
58.     vli_modMult(tmpE, tmpR, privKey, tmpN);
59.     vli_modSub(tmpE, randomK, tmpE, tmpN);
60.     vli_modMult(tmpX, tmpX, tmpE, tmpN);
61.     Uint256ToString(s, tmpX);   //s = ((1+dA)^-1 * (k - r*dA))modn
62.     memcpy(result->r, r, 32);
63.     memcpy(result->s, s, 32);
64.     free(ZA);
65.     free(e);
66.     free(x1);
67.     free(y1);
68.     free(r);
69.     free(s);
70.
71.     return result;
72. }  

2.2 数字签名的验证算法及流程




注:如果ZA_AA​不是用户A所对应的杂凑值,验证自然通不过。

1.   BOOL SM2SignatureVerify(char* message, int messageSizeInBit, SM2Signature* sign, char* IDA, uint16_t ENTLAInBit, EccPoint* G, EccPoint* pubKey)
2.  {
3.      uint256_t tmp = { 0 }, tmpN = { 0 }, num1 = { 1 };
4.
5.      for (int i = 0; i < 4; i++)
6.      {
7.          tmpN[i] = ellipticCurve_n[3 - i];
8.      }
9.      vli_modSub(tmpN, tmpN, num1, Ec->p); //因为n是大质数必定为奇数,所以这里可以直接n[0] = n[0] - 1,不必像我这样写
10.     StringToUint256(tmp, sign->r);
11.     if (IsZeroUint256(tmp) || vli_cmp(tmp, tmpN) >= 0)   //make sure r∈[1,n-1]
12.     {
13.         return FALSE;
14.     }
15.     StringToUint256(tmp, sign->s);
16.     if (IsZeroUint256(tmp) || vli_cmp(tmp, tmpN) >= 0)   //make sure s∈[1,n-1]
17.     {
18.         return FALSE;
19.     }
20.     vli_modAdd(tmpN, tmpN, num1, Ec->p);
21.
22.     //ZA = SM3(ENT LA ∥ IDA ∥ a ∥ b ∥ xG ∥ yG ∥ xA ∥ yA)。
23.     uint8_t* Z = malloc(2 + ENTLAInBit / 8 + 32 + 32 + 32 + 32 + 32 + 32), * ZA = malloc(32);
24.
25.     Z[0] = ENTLAInBit >> 8;
26.     Z[1] = ENTLAInBit & 0xff;
27.     memcpy(Z + 2, IDA, ENTLAInBit / 8);
28.     Uint256ToString(ZA, Ec->a);
29.     memcpy(Z + 2 + ENTLAInBit / 8, ZA, 32);
30.     Uint256ToString(ZA, Ec->b);
31.     memcpy(Z + 2 + ENTLAInBit / 8 + 32, ZA, 32);
32.     Uint256ToString(ZA, G->x);
33.     memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 2, ZA, 32);
34.     Uint256ToString(ZA, G->y);
35.     memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 3, ZA, 32);
36.     Uint256ToString(ZA, pubKey->x);
37.     memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 4, ZA, 32);
38.     Uint256ToString(ZA, pubKey->y);
39.     memcpy(Z + 2 + ENTLAInBit / 8 + 32 * 5, ZA, 32);
40.     SM3(Z, 2 + ENTLAInBit / 8 + 32 + 32 + 32 + 32 + 32 + 32, ZA);//ZA = SM3(ENT LA ∥ IDA ∥ a ∥ b ∥ xG ∥ yG ∥ xA ∥ yA)。
41.     free(Z);
42.
43.     uint8_t* M_ = malloc(messageSizeInBit / 8 + 32), * e = malloc(32);
44.     memcpy(M_, ZA, 32);
45.     memcpy(M_ + 32, message, messageSizeInBit / 8);
46.     SM3(M_, messageSizeInBit / 8 + 32, e);  //e=H256(M_):
47.     free(M_);
48.
49.     uint256_t tmpR = { 0 }, tmpS = { 0 }, tmpT = { 0 };
50.
51.     StringToUint256(tmpR, sign->r);
52.     StringToUint256(tmpS, sign->s);
53.     vli_modAdd(tmpT, tmpR, tmpS, tmpN); //t = (r' + s')modn
54.
55.     EccPoint* point0 = malloc(sizeof(EccPoint)), * point00 = malloc(sizeof(EccPoint)),
56.         * point1 = malloc(sizeof(EccPoint));
57.
58.     CurvePointMul(point0, G, tmpS); //point0 = s' * G
59.     CurvePointMul(point00, pubKey, tmpT);   //point00 = t * PA
60.     CurvePointAdd(point1, point0, point00); //point1 = s'*G+t*PA
61.     free(point0);
62.     free(point00);
63.
64.     uint8_t* r = malloc(32);
65.     StringToUint256(tmpT, e);   //只是把e存在tmpT里
66.     vli_modAdd(tmpR, tmpT, point1->x, tmpN);
67.     Uint256ToString(r, tmpR);
68.     free(ZA);
69.     free(e);
70.     free(point1);
71.
72.     for (int i = 0; i < 32; i++)
73.     {
74.         if (r[i] != sign->r[i])
75.         {
76.             free(r);
77.             return FALSE;
78.         }
79.     }
80.     free(r);
81.     return TRUE;
82. } 

3. 秘钥交换协议

密钥交换协议是两个用户A和B通过交互的信息传递,用各自的私钥和对方的公钥来商定一个只有他们知道的秘密密钥。这个共享的秘密密钥通常用在某个对称密码算法中。该密钥交换协议能够用于密钥管理和协商。



注:如果ZA_AA​、ZB_BB​不是用户A和B所对应的杂凑值,则自然不能达成一致的共享秘密值。

1.   BOOL KeyExchangeCheck = TRUE;//可选项,是否要验证S2 == SA以及S1 == SB
2.  BOOL SM2KeyExchange(char* IDA, uint32_t ENTLAInBit, char* IDB, uint32_t ENTLBInBit, EccPoint* G, int klenInBit)
3.  {
4.      EccPoint* RA = malloc(sizeof(EccPoint)), * V = malloc(sizeof(EccPoint)),
5.          * U = malloc(sizeof(EccPoint)),
6.          * pubKeyA = malloc(sizeof(EccPoint)), * pubKeyB = malloc(sizeof(EccPoint)),
7.          * RB = malloc(sizeof(EccPoint));
8.      uint256_t tB = { 0 }, privKeyA = { 0 }, privKeyB = { 0 };
9.      uint8_t* tmp = malloc(2 + ENTLAInBit / 8 + 32 * 6), * tmp1 = malloc(32);//用来算ZA ZB
10.
11.     GenerateKeys(privKeyA, pubKeyA, G);
12.     GenerateKeys(privKeyB, pubKeyB, G);
13.     if (!(IsValidPoint(pubKeyA, Ec) && IsValidPoint(pubKeyB, Ec)))
14.     {
15.         return FALSE;
16.     }
17.
18. #ifdef DEBUG_MODE
19.     for (int i = 0; i < 4; i++)  //测试固定随机数
20.     {
21.         privKeyA[i] = exPrivateKey_A[3 - i];
22.         privKeyB[i] = exPrivateKey_B[3 - i];
23.         pubKeyA->x[i] = exPublicKey_Ax[3 - i];
24.         pubKeyA->y[i] = exPublicKey_Ay[3 - i];
25.         pubKeyB->x[i] = exPublicKey_Bx[3 - i];
26.         pubKeyB->y[i] = exPublicKey_By[3 - i];
27.     }
28. #endif
29.     //双方的原始数据
30.     KeyExchangeAOriginalInfoDef infoA =
31.     { {0},{0},privKeyA[0],privKeyA[1],privKeyA[2],privKeyA[3],pubKeyA,pubKeyB,0,1,{0},G };
32.     KeyExchangeBOriginalInfoDef infoB =
33.     { {0},{0},privKeyB[0],privKeyB[1],privKeyB[2],privKeyB[3],pubKeyA,pubKeyB,0,1,{0},G };
34.
35.     for (int i = 0; i < 4; i++)
36.     {
37.         infoA.n[i] = ellipticCurve_n[3 - i];
38.         infoB.n[i] = ellipticCurve_n[3 - i];
39.     }
40.     infoA.w = (int)(GetMSB(infoA.n) / 2 + 1) - 1;   //w = [log2(n)/2] - 1   +1是向上取整,大质数取对数必带小数点
41.     infoB.w = infoA.w;
42.
43.     tmp[0] = ENTLAInBit >> 8;
44.     tmp[1] = ENTLAInBit & 0xff;
45.     memcpy(tmp + 2, IDA, ENTLAInBit / 8);
46.     Uint256ToString(tmp1, Ec->a);
47.     memcpy(tmp + 2 + ENTLAInBit / 8, tmp1, 32);
48.     Uint256ToString(tmp1, Ec->b);
49.     memcpy(tmp + 2 + ENTLAInBit / 8 + 32, tmp1, 32);
50.     Uint256ToString(tmp1, G->x);
51.     memcpy(tmp + 2 + ENTLAInBit / 8 + 32 * 2, tmp1, 32);
52.     Uint256ToString(tmp1, G->y);
53.     memcpy(tmp + 2 + ENTLAInBit / 8 + 32 * 3, tmp1, 32);
54.     Uint256ToString(tmp1, pubKeyA->x);
55.     memcpy(tmp + 2 + ENTLAInBit / 8 + 32 * 4, tmp1, 32);
56.     Uint256ToString(tmp1, pubKeyA->y);
57.     memcpy(tmp + 2 + ENTLAInBit / 8 + 32 * 5, tmp1, 32);
58.     SM3(tmp, 2 + ENTLAInBit / 8 + 32 * 6, infoA.ZA);
59.     memcpy(infoB.ZA, infoA.ZA, 32);
60.
61.     tmp[0] = ENTLBInBit >> 8;
62.     tmp[1] = ENTLBInBit & 0xff;
63.     memcpy(tmp + 2, IDB, ENTLBInBit / 8);
64.     Uint256ToString(tmp1, Ec->a);
65.     memcpy(tmp + 2 + ENTLBInBit / 8, tmp1, 32);
66.     Uint256ToString(tmp1, Ec->b);
67.     memcpy(tmp + 2 + ENTLBInBit / 8 + 32, tmp1, 32);
68.     Uint256ToString(tmp1, G->x);
69.     memcpy(tmp + 2 + ENTLBInBit / 8 + 32 * 2, tmp1, 32);
70.     Uint256ToString(tmp1, G->y);
71.     memcpy(tmp + 2 + ENTLBInBit / 8 + 32 * 3, tmp1, 32);
72.     Uint256ToString(tmp1, pubKeyB->x);
73.     memcpy(tmp + 2 + ENTLBInBit / 8 + 32 * 4, tmp1, 32);
74.     Uint256ToString(tmp1, pubKeyB->y);
75.     memcpy(tmp + 2 + ENTLBInBit / 8 + 32 * 5, tmp1, 32);
76.     SM3(tmp, 2 + ENTLBInBit / 8 + 32 * 6, infoB.ZB);
77.     memcpy(infoA.ZB, infoB.ZB, 32);
78.     free(tmp);
79.     free(tmp1);
80.
81.     uint256_t rA = { 0 };
82.     SM2KeyExchange_AStep1To3(RA, rA, infoA);    //A step1~3,generate RA
83.
84.     SM2KeyExchange_BStep1To4(tB, RB, infoB);    //B step1~4
85.     if (!IsValidPoint(RA, Ec))  //B 判断RA是否满足曲线方程
86.     {
87.         return FALSE;
88.     }
89.     SM2KeyExchange_BStep5To6(V, tB, RA, infoB); //B step5~6
90.     if (IsZeroPoint(V)) //B 判断V是否为(0,0)
91.     {
92.         return FALSE;
93.     }
94.
95.     uint8_t* SB = malloc(32), * KB = malloc(klenInBit / 8);
96.     SM2KeyExchange_BStep7To9(KB, SB, *V, klenInBit, *RA, *RB, infoB);   //B step7~9
97.
98.     uint256_t tA = { 0 };
99.     SM2KeyExchange_AStep4To5(tA, RA, rA, infoA);    //A step4~5
100.
101.        if (IsZeroPoint(RB))    //A 判断RB是否为(0,0)
102.        {
103.            return FALSE;
104.        }
105.
106.        SM2KeyExchange_AStep6To7(U, tA, RB, infoA); //A step6~7
107.        if (IsZeroPoint(U)) //A 判断U是否为(0,0)
108.        {
109.            return FALSE;
110.        }
111.        uint8_t* S1 = malloc(32), * KA = malloc(klenInBit / 8);
112.        SM2KeyExchange_AStep8To9(KA, S1, *U, klenInBit, *RA, *RB, infoA);   //A step8~9
113.
114.        if (KeyExchangeCheck)
115.        {
116.            for (int i = 0; i < 32; i++)//A 判断S1是否==SB
117.            {
118.                if (S1[i] != SB[i])
119.                {
120.                    return FALSE;
121.                }
122.            }
123.        }
124.
125.        uint8_t* SA = malloc(32);
126.        SM2KeyExchange_AStep10(SA, *U, *RA, *RB, infoA);    //A step10
127.
128.        uint8_t* S2 = malloc(32);
129.        SM2KeyExchange_BStep10(S2, *V, *RA, *RB, infoB);    //B step10
130.
131.        if (KeyExchangeCheck)
132.        {
133.            for (int i = 0; i < 32; i++)//B 判断S2是否==SA
134.            {
135.                if (S2[i] != SA[i])
136.                {
137.                    return FALSE;
138.                }
139.            }
140.        }
141.        free(RA);
142.        free(V);
143.        free(U);
144.        free(pubKeyA);
145.        free(pubKeyB);
146.        free(RB);
147.        free(SB);
148.        free(KB);
149.        free(S1);
150.        free(KA);
151.        free(SA);
152.        free(S2);
153.
154.        return TRUE;
155.    }  

4. 公钥加密算法

公钥加密算法规定发送者用接收者的公钥将消息加密成密文,接收者用自已的私钥对收到的密文进行解密还原成原始消息。

4.1 加密算法


1.   uint8_t* SM2Encrypt(char* messagePlain, int messageSizeInBit, EccPoint* pubKey)
2.  {
3.      uint256_t randomK = { 0 };
4.      EccPoint* pointC1 = malloc(sizeof(EccPoint)), * kPb = malloc(sizeof(EccPoint));
5.      uint8_t* t = malloc(messageSizeInBit / 8), * x2 = malloc(64), * y2 = malloc(32),//t = KDF()
6.          * C1 = malloc(65), * x1 = malloc(32), * y1 = malloc(32),
7.          * C2 = malloc(messageSizeInBit / 8), * C3 = malloc(64 + messageSizeInBit / 8),
8.          * C = malloc(65 + messageSizeInBit / 8 + 32);
9.      GetRandomNumber(randomK, Ec->p);
10. #ifdef DEBUG_MODE
11.     for (int i = 0; i < 4; i++)  //测试时随机数先固定
12.     {
13.         randomK[i] = exRandomK[3 - i];
14.     }
15. #endif
16.     CalculateC1(pointC1, randomK, G);
17.     Uint256ToString(x1, pointC1->x);
18.     Uint256ToString(y1, pointC1->y);
19.     C1[0] = 0x04;
20.     memcpy(C1 + 1, x1, 32);
21.     memcpy(C1 + 33, y1, 32);//C1 = 04||x1||y1
22.
23.     CalculateKPb(kPb, randomK, pubKey);
24.     Uint256ToString(x2, kPb->x);
25.     Uint256ToString(y2, kPb->y);
26.
27.     memcpy(C3, x2, 32);
28.     memcpy(C3 + 32, messagePlain, messageSizeInBit / 8);
29.     memcpy(C3 + 32 + messageSizeInBit / 8, y2, 32);
30.
31.     memcpy(x2 + 32, y2, 32);//x2 = x2 || y2
32.     KDF(t, x2, 64 * 8, messageSizeInBit);   //t = KDF()
33.     CalculateC2(C2, messagePlain, t, messageSizeInBit / 8); //C2 = M^t
34.     SM3((uint8_t*)C3, 64 + messageSizeInBit / 8, (uint8_t*)C3); //C3 = SM3(x2||M||y2)
35.
36.     memcpy(C, C1, 65);
37.     memcpy(C + 65, C2, messageSizeInBit / 8);
38.     memcpy(C + 65 + messageSizeInBit / 8, C3, 32);  //C = C1 || C2 || C3
39.     free(pointC1);
40.     free(kPb);
41.     free(t);
42.     free(x2);
43.     free(y2);
44.     free(C1);
45.     free(x1);
46.     free(y1);
47.     free(C2);
48.     free(C3);
49.
50.     return C;
51. }  

4.2 解密算法



1.   uint8_t* SM2Decrypt(char* C, int lenInByte, uint64_t* privKey)
2.  {
3.      EccPoint* pointC1 = malloc(sizeof(EccPoint)), * point2 = malloc(sizeof(EccPoint));
4.      int lenOfMsg = lenInByte - 65 - 32;
5.      uint8_t* C2 = malloc(lenOfMsg + 1), * msg = malloc(lenOfMsg + 1),
6.          * x1 = malloc(32), * y1 = malloc(32),
7.          * x2 = malloc(64), * y2 = malloc(32), * t = malloc(lenOfMsg);
8.
9.      msg[lenInByte - 65 - 32] = '\0';
10.     memcpy(C2, C + 65, lenInByte - 65 - 32);//密文msg
11.     memcpy(x1, C + 1, 32);
12.     memcpy(y1, C + 1 + 32, 32);
13.     StringToUint256(pointC1->x, x1);
14.     StringToUint256(pointC1->y, y1);
15.     CurvePointMul(point2, pointC1, privKey);
16.     Uint256ToString(x2, point2->x);
17.     Uint256ToString(y2, point2->y);
18.     memcpy(x2 + 32, y2, 32);    //x2 = x2 || y2
19.     KDF(t, x2, 64 * 8, (lenInByte - 65 - 32) * 8);//t = KDF(x2||y2,klenInBit)
20.     CalculateMessage(msg, C2, t, lenOfMsg); //M' = C2 ^ t
21.     free(pointC1);
22.     free(point2);
23.     free(C2);
24.     free(x1);
25.     free(y1);
26.     free(x2);
27.     free(y2);
28.     free(t);
29.
30.     return msg;
31. }  

国密SM2/SM3算法在单片机平台上的实现(C语言)相关推荐

  1. 国密SM2,SM3,SM4的前后台(js和java)加解密写法

    目录 SM2加解密 js java SM3加密 js java sm3前后台(js/java)加密不一致原因 SM4加解密 js java 之前做一个项目的时候需要用到国密SM2,SM3,SM4的加解 ...

  2. vue前端国密SM2, SM4 算法实现

    vue前端国密SM2, SM4 算法实现 整体加密逻辑是,首先生成16位key值 用SM2 公钥加密该key值,后端用sm2私钥 解密出key值,然后采用sm4方法根据key值对返回值进行加密,前端采 ...

  3. php gmssl,支持国密SM2/SM3/SM4/SM9/ZUC/SSL的密码工具箱GmSSL

    GmSSL概述 GmSSL是一个开源的密码工具箱,支持SM2/SM3/SM4/SM9/ZUC等国密(国家商用密码)算法.SM2国密数字证书及基于SM2证书的SSL/TLS安全通信协议,支持国密硬件密码 ...

  4. 通过网页查看服务器算法,服务器使用国密(SM2/SM3/SM4)证书,通过浏览器访问

    1. Apache + Gmssl Apache 本身不支持国密,需要修改代码支持GMTLS 下载解压: wget http://archive.apache.org/dist/httpd/httpd ...

  5. PB实现国密SM2/SM3/SM4算法(DLL方式)

    文章目录 SM4 SM4简介 分组加密模式ECB与CBC ECB模式加密解密 CBC模式加密解密 SM3 SM3简介 SM3摘要生成 SM3WithSM2摘要生成 SM2 SM2简介 SM2签名与验签 ...

  6. java sm9_一个支持国密SM2/SM3/SM4/SM9/ZUC/SSL的密码工具箱

    The GmSSL Project 网址:http://gmssl.org/docs/quickstart.html 在网上闲逛时发现一个工具.SSL支持国密算法.看着比较高大上.还没有用呢.记下来. ...

  7. OpenSSL 1.1.1 新特性: 全面支持国密SM2/SM3/SM4加密算法

    OpenSSL项目最近6个月添加了许多新特性, 包括对中国SM2/SM3/SM4算法的支持: SM2椭圆曲线: https://github.com/openssl/openssl/pull/4793 ...

  8. 国密 sm2,sm3,sm4 算法纯 JavaScript 实现

    2014 年国务院办公厅就颁发了<国务院办公厅转发密码局等部门关于金融领域密码应用指导意见>,指出在我国涉及到金融领域信息安全的产品和系统要自主可控,在金融领域使用国产加密标准是机构走向合 ...

  9. 服务器使用国密(SM2/SM3/SM4)证书,通过浏览器访问

    1. Apache + Gmssl Apache 本身不支持国密,需要修改代码支持GMTLS 下载解压: wget http://archive.apache.org/dist/httpd/httpd ...

  10. java sm_Java国密SM2/SM3/SM4及证书

    1. 使用BC库1.59版本已经可以支持国密算法SM2/SM3/SM4,某大神写的详细测试例子:https://github.com/ZZMarquis/gmhelper 2. 制作证书参考网上资料简 ...

最新文章

  1. IOS使用正则表达式去掉html中的标签元素,获得纯文本
  2. this指向总结(无栗子)
  3. 快速写出较好CSS的5种方法
  4. SpringBoot高级-检索-Elasticsearch简介安装
  5. 生产环境该如何选择lvs的工作模式,和哪一种算法
  6. 使用.Net Core编写命令行工具(CLI)
  7. (转)Spring Boot 2 (八):Spring Boot 集成 Memcached
  8. python什么学历能学_自考学历找工作,钱少点也没关系?
  9. MySQL-InnoDB-事务
  10. 实习、竞赛、论文?关于计算机读研的一些小建议!
  11. 485串口测试工具软件_【实例】如何用串口软件调试变频器?
  12. 流水作业调度问题 Johnson 算法
  13. Navicat Premium 11.2.7 中文破解版安装
  14. 华为ensp 和secureCRT 连接
  15. true launch bar 完美运行版——快速启动工具
  16. 概率与数理统计学习总结四---连续型随机变量及其概率密度
  17. Java 常见摘要算法——md5、sha1、sha256
  18. 如何将Excel多行单元格文字合并到一个单元格中
  19. Echarts地图标记重合问题原因
  20. 7-6 输出月份对应的英文名称 (10 分)

热门文章

  1. 基于深度学习的人脸表情识别实现
  2. 百度云网盘高速通道加速破解版 去广告纯净版干净云
  3. PHP 导出excel
  4. 安装并启动Tomcat 8(mac版本)
  5. 美创科技荣获国家信息安全漏洞库(CNNVD)技术支撑单位
  6. 《软件工程导论》复习知识点总结
  7. 《集成电路先进光刻技术与版图设计优化》课程分享之一:典型显微系统的光学成像原理
  8. PB如何配置数据源及自带的PB系统
  9. 给Eclipse设置android的SDK位置时,出现这个:This Android SDK requires Andr...ate ADT to the latest
  10. ArcGIS软件中的坐标系及数据类型的概念