Skip to content

Commit 1d99265

Browse files
committed
[fix] 修正SM4加解密。close: #151
1 parent 80a1b57 commit 1d99265

File tree

3 files changed

+29
-6
lines changed

3 files changed

+29
-6
lines changed

NewLife.Core/Security/PKCS7PaddingTransform.cs

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Security.Cryptography;
2-
using NewLife.Collections;
32

43
namespace NewLife.Security;
54

@@ -114,10 +113,10 @@ public Int32 TransformBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCo
114113
/// <returns></returns>
115114
public Byte[] TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
116115
{
117-
if (inputCount == 0) return [];
118-
119116
if (_encryptMode)
120117
{
118+
if (inputCount == 0) return [];
119+
121120
var paddingLength = InputBlockSize - (inputCount % InputBlockSize);
122121
var paddingValue = _mode switch
123122
{
@@ -150,6 +149,8 @@ public Byte[] TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 i
150149
}
151150
else
152151
{
152+
if (inputCount == 0 && !_hasWithheldBlock) return [];
153+
153154
var data = _transform.TransformFinalBlock(inputBuffer, inputOffset, inputCount);
154155
if (_hasWithheldBlock)
155156
{
@@ -165,13 +166,15 @@ public Byte[] TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 i
165166
var paddingValue = _mode == PaddingMode.ANSIX923 ? 0 : paddingLength;
166167
var paddingError = 0;
167168
if (_mode != PaddingMode.ISO10126)
169+
{
168170
for (var i = OutputBlockSize; i >= 1; i--)
169171
{
170172
// if i > paddingLength ignore;
171173
// if paddingLength != data[data.Length - i] error;
172174
var posMask = ~(paddingLength - i) >> 31;
173175
paddingError |= (paddingValue ^ data[data.Length - i]) & posMask;
174176
}
177+
}
175178

176179
if (paddingError != 0 || paddingLength == 0 || paddingLength > OutputBlockSize)
177180
throw new CryptographicException("Invalid padding");

NewLife.Core/Security/SM4.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
using System.Buffers.Binary;
88
#endif
99

10+
namespace NewLife.Security;
11+
1012
/// <summary>SM4(国密4)</summary>
1113
public class SM4 : SymmetricAlgorithm
1214
{
@@ -244,7 +246,7 @@ public SM4Transform(Byte[] key, Byte[]? iv, Boolean encryptMode)
244246
}
245247

246248
/// <summary>销毁</summary>
247-
public void Dispose() { }
249+
void IDisposable.Dispose() { }
248250
#endregion
249251

250252
/// <summary>块加密数据,传入缓冲区必须是整块数据</summary>

XUnitTest.Core/Security/SM4Tests.cs

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
using System.Security.Cryptography;
22
using System.Text;
33
using NewLife;
4+
using NewLife.Security;
5+
using Org.BouncyCastle.Crypto;
46
using Org.BouncyCastle.Crypto.Engines;
57
using Org.BouncyCastle.Crypto.Parameters;
6-
using Org.BouncyCastle.Crypto;
78
using Xunit;
8-
using System;
99

1010
namespace XUnitTest.Security;
1111

@@ -26,6 +26,24 @@ public void SM4_ECB_PKCS7_Test()
2626
Assert.Equal(text, text3);
2727
}
2828

29+
/// <summary>
30+
/// https://github.com/NewLifeX/X/issues/151
31+
/// </summary>
32+
[Fact]
33+
public void SM4_ECB_PKCS7_Test_Chinese()
34+
{
35+
var text = "中国人民万岁";
36+
var key = "sasdx-asdas-111".GetBytes();
37+
38+
var sm4 = SM4.Create();
39+
var text2 = sm4.Encrypt(text.GetBytes(), key, CipherMode.ECB, PaddingMode.PKCS7).ToBase64();
40+
Assert.Equal("5ivCW7pfHwb8eb0FygSLa1GG7RsVIRF8ymOHZmOS1+A=", text2);
41+
42+
var sm42 = SM4.Create();
43+
var text3 = sm42.Decrypt(text2.ToBase64(), key, CipherMode.ECB, PaddingMode.PKCS7).ToStr();
44+
Assert.Equal(text, text3);
45+
}
46+
2947
[Fact]
3048
public void SM4_ECB_Zeros_Test()
3149
{

0 commit comments

Comments
 (0)