fix(tenpayv3): 修复部分响应模型解密敏感数据字段时抛出异常的问题

This commit is contained in:
Fu Diwei
2021-12-03 16:27:13 +08:00
parent 9423dd5642
commit ec6e3f7e7a
28 changed files with 120 additions and 58 deletions

View File

@@ -23,55 +23,59 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
try
{
// 遍历并加密被标记为敏感数据的字段
Utilities.ReflectionUtility.ReplacePropertyStringValue(ref request, (obj, prop, value) =>
bool requireEncrypt = request.GetType().GetCustomAttributes<WechatTenpaySensitiveAttribute>(inherit: true).Any();
if (requireEncrypt)
{
var attr = prop.GetCustomAttribute<WechatTenpaySensitivePropertyAttribute>();
if (attr == null)
return value;
if (Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB.Equals(attr.Algorithm))
// 遍历并加密被标记为敏感数据的字段
Utilities.ReflectionUtility.ReplacePropertyStringValue(ref request, (obj, prop, value) =>
{
if (client.CertificateManager == null)
throw new Exceptions.WechatTenpayRequestEncryptionException("Encrypt request failed, because there is no platform certificate in the manager.");
var attr = prop.GetCustomAttribute<WechatTenpaySensitivePropertyAttribute>();
if (attr == null)
return value;
string certificate;
if (!string.IsNullOrEmpty(request.WechatpayCertSerialNumber))
if (Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB.Equals(attr.Algorithm))
{
// 如果已在请求中指定特定的平台证书序列号,直接从管理器中取值
var cert = client.CertificateManager.GetEntry(request.WechatpayCertSerialNumber!);
if (!cert.HasValue)
if (client.CertificateManager == null)
throw new Exceptions.WechatTenpayRequestEncryptionException("Encrypt request failed, because there is no platform certificate in the manager.");
string certificate;
if (!string.IsNullOrEmpty(request.WechatpayCertSerialNumber))
{
throw new Exceptions.WechatTenpayEventVerificationException("Encrypt request failed, because there is no platform certificate matched the serial number.");
// 如果已在请求中指定特定的平台证书序列号,直接从管理器中取值
var cert = client.CertificateManager.GetEntry(request.WechatpayCertSerialNumber!);
if (!cert.HasValue)
{
throw new Exceptions.WechatTenpayEventVerificationException("Encrypt request failed, because there is no platform certificate matched the serial number.");
}
certificate = cert.Value.Certificate;
}
else
{
// 如果未在请求中指定特定的平台证书序列号,从管理器中取过期时间最远的
var certs = client.CertificateManager.AllEntries().OrderByDescending(e => e.ExpireTime);
if (!certs.Any())
{
throw new Exceptions.WechatTenpayEventVerificationException("Encrypt request failed, because there is no platform certificate in the manager.");
}
var cert = certs.First();
certificate = cert.Certificate;
request.WechatpayCertSerialNumber = cert.SerialNumber;
}
certificate = cert.Value.Certificate;
return Utilities.RSAUtility.EncryptWithECBByCertificate(
certificate: certificate,
plainText: value
);
}
else
{
// 如果未在请求中指定特定的平台证书序列号,从管理器中取过期时间最远的
var certs = client.CertificateManager.AllEntries().OrderByDescending(e => e.ExpireTime);
if (!certs.Any())
{
throw new Exceptions.WechatTenpayEventVerificationException("Encrypt request failed, because there is no platform certificate in the manager.");
}
var cert = certs.First();
certificate = cert.Certificate;
request.WechatpayCertSerialNumber = cert.SerialNumber;
throw new Exceptions.WechatTenpayRequestEncryptionException("Unsupported encryption algorithm.");
}
return Utilities.RSAUtility.EncryptWithECBByCertificate(
certificate: certificate,
plainText: value
);
}
else
{
throw new Exceptions.WechatTenpayRequestEncryptionException("Unsupported encryption algorithm.");
}
});
});
}
}
catch (Exception ex) when (!(ex is Exceptions.WechatTenpayRequestEncryptionException))
{

View File

@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Reflection;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
@@ -54,25 +55,29 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
return response;
}
// 遍历并解密被标记为敏感数据的字段
Utilities.ReflectionUtility.ReplacePropertyStringValue(ref response, (obj, prop, value) =>
bool requireDecrypt = response.GetType().GetCustomAttributes<WechatTenpaySensitiveAttribute>(inherit: true).Any();
if (requireDecrypt)
{
var attr = prop.GetCustomAttribute<WechatTenpaySensitivePropertyAttribute>();
if (attr == null)
return value;
// 遍历并解密被标记为敏感数据的字段
Utilities.ReflectionUtility.ReplacePropertyStringValue(ref response, (obj, prop, value) =>
{
var attr = prop.GetCustomAttribute<WechatTenpaySensitivePropertyAttribute>();
if (attr == null)
return value;
if (Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB.Equals(attr.Algorithm))
{
return Utilities.RSAUtility.DecryptWithECB(
privateKey: client.Credentials.MerchantCertPrivateKey,
cipherText: value
);
}
else
{
throw new Exceptions.WechatTenpayResponseDecryptionException("Unsupported decryption algorithm.");
}
});
if (Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB.Equals(attr.Algorithm))
{
return Utilities.RSAUtility.DecryptWithECB(
privateKey: client.Credentials.MerchantCertPrivateKey,
cipherText: value
);
}
else
{
throw new Exceptions.WechatTenpayResponseDecryptionException("Unsupported decryption algorithm.");
}
});
}
}
catch (Exception ex) when (!(ex is Exceptions.WechatTenpayResponseDecryptionException))
{