Skip to content

Commit a061f66

Browse files
committed
refactor: 在 .NET 5.0+ 目标框架下将 AES、RSA 算法工具类的部分实现使用标准库原生方式重写
1 parent be37ab0 commit a061f66

File tree

16 files changed

+408
-167
lines changed

16 files changed

+408
-167
lines changed

src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/AESUtility.cs

Lines changed: 56 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -88,31 +88,38 @@ public static byte[] DecryptWithGCM(byte[] keyBytes, byte[] nonceBytes, byte[]?
8888
if (cipherBytes.Length < TAG_LENGTH_BYTE) throw new ArgumentException($"Invalid cipher byte length (expected: more than {TAG_LENGTH_BYTE}, actual: {cipherBytes.Length}).", nameof(cipherBytes));
8989

9090
#if NET5_0_OR_GREATER
91-
using (AesGcm aes = new AesGcm(keyBytes))
91+
if (AesGcm.IsSupported)
9292
{
93-
byte[] cipherWithoutTagBytes = new byte[cipherBytes.Length - TAG_LENGTH_BYTE];
94-
byte[] tagBytes = new byte[TAG_LENGTH_BYTE];
95-
Buffer.BlockCopy(cipherBytes, 0, cipherWithoutTagBytes, 0, cipherWithoutTagBytes.Length);
96-
Buffer.BlockCopy(cipherBytes, cipherWithoutTagBytes.Length, tagBytes, 0, tagBytes.Length);
93+
if (!string.Equals(paddingMode, PADDING_MODE_NOPADDING, StringComparison.OrdinalIgnoreCase))
94+
throw new NotSupportedException();
9795

98-
byte[] plainBytes = new byte[cipherWithoutTagBytes.Length];
99-
aes.Decrypt(nonceBytes, cipherWithoutTagBytes, tagBytes, plainBytes, associatedDataBytes);
100-
return plainBytes;
96+
using (AesGcm aes = new AesGcm(keyBytes))
97+
{
98+
byte[] cipherWithoutTagBytes = new byte[cipherBytes.Length - TAG_LENGTH_BYTE];
99+
byte[] tagBytes = new byte[TAG_LENGTH_BYTE];
100+
Buffer.BlockCopy(cipherBytes, 0, cipherWithoutTagBytes, 0, cipherWithoutTagBytes.Length);
101+
Buffer.BlockCopy(cipherBytes, cipherWithoutTagBytes.Length, tagBytes, 0, tagBytes.Length);
102+
103+
byte[] plainBytes = new byte[cipherWithoutTagBytes.Length];
104+
aes.Decrypt(nonceBytes, cipherWithoutTagBytes, tagBytes, plainBytes, associatedDataBytes);
105+
return plainBytes;
106+
}
101107
}
102-
#else
103-
IBufferedCipher cipher = CipherUtilities.GetCipher($"AES/GCM/{paddingMode}");
104-
ICipherParameters cipherParams = new AeadParameters(
105-
new KeyParameter(keyBytes),
106-
TAG_LENGTH_BYTE * 8,
107-
nonceBytes,
108-
associatedDataBytes
109-
);
110-
cipher.Init(false, cipherParams);
111-
byte[] plainBytes = new byte[cipher.GetOutputSize(cipherBytes.Length)];
112-
int len = cipher.ProcessBytes(cipherBytes, 0, cipherBytes.Length, plainBytes, 0);
113-
cipher.DoFinal(plainBytes, len);
114-
return plainBytes;
115108
#endif
109+
{
110+
IBufferedCipher cipher = CipherUtilities.GetCipher($"AES/GCM/{paddingMode}");
111+
ICipherParameters cipherParams = new AeadParameters(
112+
new KeyParameter(keyBytes),
113+
TAG_LENGTH_BYTE * 8,
114+
nonceBytes,
115+
associatedDataBytes
116+
);
117+
cipher.Init(false, cipherParams);
118+
byte[] plainBytes = new byte[cipher.GetOutputSize(cipherBytes.Length)];
119+
int len = cipher.ProcessBytes(cipherBytes, 0, cipherBytes.Length, plainBytes, 0);
120+
cipher.DoFinal(plainBytes, len);
121+
return plainBytes;
122+
}
116123
}
117124

118125
/// <summary>
@@ -204,32 +211,38 @@ public static byte[] EncryptWithGCM(byte[] keyBytes, byte[] nonceBytes, byte[]?
204211
if (plainBytes is null) throw new ArgumentNullException(nameof(plainBytes));
205212

206213
#if NET5_0_OR_GREATER
207-
using (AesGcm aes = new AesGcm(keyBytes))
214+
if (AesGcm.IsSupported)
208215
{
209-
byte[] cipherBytes = new byte[plainBytes.Length];
210-
byte[] tagBytes = new byte[TAG_LENGTH_BYTE];
211-
aes.Encrypt(nonceBytes, plainBytes, cipherBytes, tagBytes, associatedDataBytes);
216+
if (!string.Equals(paddingMode, PADDING_MODE_NOPADDING, StringComparison.OrdinalIgnoreCase))
217+
throw new NotSupportedException();
212218

213-
byte[] cipherWithTagBytes = new byte[cipherBytes.Length + tagBytes.Length];
214-
Buffer.BlockCopy(cipherBytes, 0, cipherWithTagBytes, 0, cipherBytes.Length);
215-
Buffer.BlockCopy(tagBytes, 0, cipherWithTagBytes, cipherBytes.Length, tagBytes.Length);
216-
return cipherWithTagBytes;
217-
}
218-
#else
219+
using (AesGcm aes = new AesGcm(keyBytes))
220+
{
221+
byte[] cipherBytes = new byte[plainBytes.Length];
222+
byte[] tagBytes = new byte[TAG_LENGTH_BYTE];
223+
aes.Encrypt(nonceBytes, plainBytes, cipherBytes, tagBytes, associatedDataBytes);
219224

220-
IBufferedCipher cipher = CipherUtilities.GetCipher($"AES/GCM/{paddingMode}");
221-
ICipherParameters cipherParams = new AeadParameters(
222-
new KeyParameter(keyBytes),
223-
TAG_LENGTH_BYTE * 8,
224-
nonceBytes,
225-
associatedDataBytes
226-
);
227-
cipher.Init(true, cipherParams);
228-
byte[] cipherBytes = new byte[cipher.GetOutputSize(plainBytes.Length)];
229-
int len = cipher.ProcessBytes(plainBytes, 0, plainBytes.Length, cipherBytes, 0);
230-
cipher.DoFinal(cipherBytes, len);
231-
return cipherBytes;
225+
byte[] cipherWithTagBytes = new byte[cipherBytes.Length + tagBytes.Length];
226+
Buffer.BlockCopy(cipherBytes, 0, cipherWithTagBytes, 0, cipherBytes.Length);
227+
Buffer.BlockCopy(tagBytes, 0, cipherWithTagBytes, cipherBytes.Length, tagBytes.Length);
228+
return cipherWithTagBytes;
229+
}
230+
}
232231
#endif
232+
{
233+
IBufferedCipher cipher = CipherUtilities.GetCipher($"AES/GCM/{paddingMode}");
234+
ICipherParameters cipherParams = new AeadParameters(
235+
new KeyParameter(keyBytes),
236+
TAG_LENGTH_BYTE * 8,
237+
nonceBytes,
238+
associatedDataBytes
239+
);
240+
cipher.Init(true, cipherParams);
241+
byte[] cipherBytes = new byte[cipher.GetOutputSize(plainBytes.Length)];
242+
int len = cipher.ProcessBytes(plainBytes, 0, plainBytes.Length, cipherBytes, 0);
243+
cipher.DoFinal(cipherBytes, len);
244+
return cipherBytes;
245+
}
233246
}
234247

235248
/// <summary>

src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/RSAUtility.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ public static class RSAUtility
2323

2424
private static byte[] ConvertPrivateKeyPemToByteArray(string privateKeyPem)
2525
{
26-
if (!privateKeyPem.StartsWith("-----BEGIN PRIVATE KEY-----"))
26+
const string PKCS8_HEADER = "-----BEGIN PRIVATE KEY-----";
27+
const string PKCS8_FOOTER = "-----END PRIVATE KEY-----";
28+
29+
if (!privateKeyPem.StartsWith(PKCS8_HEADER))
2730
{
2831
using (TextReader textReader = new StringReader(privateKeyPem))
2932
using (PemReader pemReader = new PemReader(textReader))
@@ -56,15 +59,18 @@ private static byte[] ConvertPrivateKeyPemToByteArray(string privateKeyPem)
5659
}
5760

5861
privateKeyPem = privateKeyPem
59-
.Replace("-----BEGIN PRIVATE KEY-----", string.Empty)
60-
.Replace("-----END PRIVATE KEY-----", string.Empty);
62+
.Replace(PKCS8_HEADER, string.Empty)
63+
.Replace(PKCS8_FOOTER, string.Empty);
6164
privateKeyPem = Regex.Replace(privateKeyPem, "\\s+", string.Empty);
6265
return Convert.FromBase64String(privateKeyPem);
6366
}
6467

6568
private static byte[] ConvertPublicKeyPemToByteArray(string publicKeyPem)
6669
{
67-
if (!publicKeyPem.StartsWith("-----BEGIN PUBLIC KEY-----"))
70+
const string PKCS8_HEADER = "-----BEGIN PUBLIC KEY-----";
71+
const string PKCS8_FOOTER = "-----END PUBLIC KEY-----";
72+
73+
if (!publicKeyPem.StartsWith(PKCS8_HEADER))
6874
{
6975
using (TextReader textReader = new StringReader(publicKeyPem))
7076
using (PemReader pemReader = new PemReader(textReader))
@@ -91,8 +97,8 @@ private static byte[] ConvertPublicKeyPemToByteArray(string publicKeyPem)
9197
}
9298

9399
publicKeyPem = publicKeyPem
94-
.Replace("-----BEGIN PUBLIC KEY-----", string.Empty)
95-
.Replace("-----END PUBLIC KEY-----", string.Empty);
100+
.Replace(PKCS8_HEADER, string.Empty)
101+
.Replace(PKCS8_FOOTER, string.Empty);
96102
publicKeyPem = Regex.Replace(publicKeyPem, "\\s+", string.Empty);
97103
return Convert.FromBase64String(publicKeyPem);
98104
}

src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/__Internal/WechatTenpayBusinessClientSigningExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public static ErroredResult VerifySignature(this WechatTenpayBusinessClient clie
6363
break;
6464
}
6565

66-
bool valid = Utilities.RSAUtility.Verify(
66+
bool valid = Utilities.RSAUtility.VerifyWithSHA256(
6767
publicKeyPem: client.Credentials.TBEPCertificatePublicKey,
6868
messageData: GenerateMessageForSignature(timestamp: strTimestamp, nonce: strNonce, body: strContent),
6969
encodingSignature: new EncodedString(strSignature, EncodingKinds.Base64)

src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Interceptors/WechatTenpayBusinessRequestSigningInterceptor.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,13 @@ public override async Task BeforeCallAsync(HttpInterceptorContext context, Cance
7575
{
7676
try
7777
{
78-
sign = Utilities.RSAUtility.Sign(_platformCertPk, signData).Value!;
78+
sign = Utilities.RSAUtility.SignWithSHA256(_platformCertPk, signData).Value!;
7979

8080
if (softSignRequired)
8181
{
8282
byte[] keyBytes = EncodedString.FromBase64String(_enterpriseCertPk!);
8383
byte[] msgBytes = EncodedString.FromBase64String(sign);
84-
softSign = EncodedString.ToBase64String(Utilities.RSAUtility.Sign(keyBytes, msgBytes)).Value!;
84+
softSign = EncodedString.ToBase64String(Utilities.RSAUtility.SignWithSHA256(keyBytes, msgBytes)).Value!;
8585
}
8686
}
8787
catch (Exception ex)

0 commit comments

Comments
 (0)