chore(tenpayv3): 升级依赖库

This commit is contained in:
fudiwei
2022-12-02 17:29:32 +08:00
parent 1eb72bba16
commit 718125e211
3 changed files with 78 additions and 91 deletions

View File

@@ -40,8 +40,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="BouncyCastle.Cryptography" Version="2.0.0" />
<PackageReference Include="System.ValueTuple" Version="4.5.0" Condition="'$(TargetFramework)' == 'net461'" /> <PackageReference Include="System.ValueTuple" Version="4.5.0" Condition="'$(TargetFramework)' == 'net461'" />
<PackageReference Include="Portable.BouncyCastle" Version="1.9.0" />
<PackageReference Include="SKIT.FlurlHttpClient.Common" Version="2.5.0" /> <PackageReference Include="SKIT.FlurlHttpClient.Common" Version="2.5.0" />
</ItemGroup> </ItemGroup>

View File

@@ -104,24 +104,6 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
return new ECPublicKeyParameters(SM2_ECX9_PARAMS.Curve.CreatePoint(ecPublicKeyParamsX, ecPublicKeyParamsY), SM2_DOMAIN_PARAMS); return new ECPublicKeyParameters(SM2_ECX9_PARAMS.Curve.CreatePoint(ecPublicKeyParamsX, ecPublicKeyParamsY), SM2_DOMAIN_PARAMS);
} }
private static byte[] ConvertC1C3C2ToC1C2C3(byte[] c1c3c2)
{
byte[] tmp = new byte[c1c3c2.Length];
Buffer.BlockCopy(c1c3c2, 0, tmp, 0, SM2_C1_LENGTH);
Buffer.BlockCopy(c1c3c2, SM2_C1_LENGTH + SM2_C3_LENGTH, tmp, SM2_C1_LENGTH, c1c3c2.Length - SM2_C1_LENGTH - SM2_C3_LENGTH);
Buffer.BlockCopy(c1c3c2, SM2_C1_LENGTH, tmp, c1c3c2.Length - SM2_C3_LENGTH, SM2_C3_LENGTH);
return tmp;
}
private static byte[] ConvertC1C2C3ToC1C3C2(byte[] c1c2c3)
{
byte[] tmp = new byte[c1c2c3.Length];
Buffer.BlockCopy(c1c2c3, 0, tmp, 0, SM2_C1_LENGTH); //c1
Buffer.BlockCopy(c1c2c3, c1c2c3.Length - SM2_C3_LENGTH, tmp, SM2_C1_LENGTH, SM2_C3_LENGTH);
Buffer.BlockCopy(c1c2c3, SM2_C1_LENGTH, tmp, SM2_C1_LENGTH + SM2_C3_LENGTH, c1c2c3.Length - SM2_C1_LENGTH - SM2_C3_LENGTH);
return tmp;
}
private static byte[] ConvertC1C3C2ToAsn1(byte[] c1c3c2) private static byte[] ConvertC1C3C2ToAsn1(byte[] c1c3c2)
{ {
byte[] c1 = Arrays.CopyOfRange(c1c3c2, 0, SM2_C1_LENGTH); byte[] c1 = Arrays.CopyOfRange(c1c3c2, 0, SM2_C1_LENGTH);
@@ -263,25 +245,17 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
cipherBytes = tmp; cipherBytes = tmp;
} }
// BouncyCastle 库对 SM2 的加密结果为 C1|C2|C3但国标要求为 C1|C3|C2 SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
// 此工具类仅支持国标(也是微信支付所要求的),所以先转换一次入参的密文数据
cipherBytes = ConvertC1C3C2ToC1C2C3(cipherBytes);
SM2Engine sm2Engine = new SM2Engine();
sm2Engine.Init(false, sm2PrivateKeyParams); sm2Engine.Init(false, sm2PrivateKeyParams);
return sm2Engine.ProcessBlock(cipherBytes, 0, cipherBytes.Length); return sm2Engine.ProcessBlock(cipherBytes, 0, cipherBytes.Length);
} }
private static byte[] Encrypt(ECPublicKeyParameters sm2PublicKeyParams, byte[] plainBytes, bool asn1Encoding) private static byte[] Encrypt(ECPublicKeyParameters sm2PublicKeyParams, byte[] plainBytes, bool asn1Encoding)
{ {
SM2Engine sm2Engine = new SM2Engine(); SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);
sm2Engine.Init(true, new ParametersWithRandom(sm2PublicKeyParams, new SecureRandom())); sm2Engine.Init(true, new ParametersWithRandom(sm2PublicKeyParams, new SecureRandom()));
byte[] cipherBytes = sm2Engine.ProcessBlock(plainBytes, 0, plainBytes.Length); byte[] cipherBytes = sm2Engine.ProcessBlock(plainBytes, 0, plainBytes.Length);
// BouncyCastle 库对 SM2 的加密结果为 C1|C2|C3但国标 GM/T 0009-2012 要求为 C1|C3|C2
// 此工具类仅支持国标(也是微信支付所要求的),所以先转换一次出参的密文数据
cipherBytes = ConvertC1C2C3ToC1C3C2(cipherBytes);
// BouncyCastle 库的加密结果默认非 ASN.1 编码,如有需要需要手动转换 // BouncyCastle 库的加密结果默认非 ASN.1 编码,如有需要需要手动转换
if (asn1Encoding) if (asn1Encoding)
{ {

View File

@@ -73,99 +73,112 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
internal abstract class GeneralDigest : IDigest internal abstract class GeneralDigest : IDigest
{ {
private const int ByteLength = 64; private const int BYTE_LENGTH = 64;
private readonly byte[] XBuf;
private int XBufOff; private readonly byte[] _xBuffer;
private long ByteCount; private int _xBufferOff;
private long _byteCount;
public abstract string AlgorithmName { get; } public abstract string AlgorithmName { get; }
protected GeneralDigest() protected GeneralDigest()
{ {
XBuf = new byte[4]; _xBuffer = new byte[4];
} }
protected GeneralDigest(GeneralDigest t) protected GeneralDigest(GeneralDigest t)
{ {
XBuf = new byte[t.XBuf.Length]; _xBuffer = new byte[t._xBuffer.Length];
Array.Copy(t.XBuf, 0, XBuf, 0, t.XBuf.Length); Array.Copy(t._xBuffer, 0, _xBuffer, 0, t._xBuffer.Length);
XBufOff = t.XBufOff; _xBufferOff = t._xBufferOff;
ByteCount = t.ByteCount; _byteCount = t._byteCount;
}
public abstract int GetDigestSize();
public int GetByteLength()
{
return BYTE_LENGTH;
} }
public void Update(byte input) public void Update(byte input)
{ {
XBuf[XBufOff++] = input; _xBuffer[_xBufferOff++] = input;
if (XBufOff == XBuf.Length) if (_xBufferOff == _xBuffer.Length)
{ {
ProcessWord(XBuf, 0); ProcessWord(_xBuffer, 0);
XBufOff = 0; _xBufferOff = 0;
} }
ByteCount++; _byteCount++;
} }
public void BlockUpdate(byte[] input, int inOff, int length) public void BlockUpdate(byte[] input, int inOff, int inLen)
{ {
while ((XBufOff != 0) && (length > 0)) while ((_xBufferOff != 0) && (inLen > 0))
{ {
Update(input[inOff]); Update(input[inOff]);
inOff++; inOff++;
length--; inLen--;
} }
while (length > XBuf.Length) while (inLen > _xBuffer.Length)
{ {
ProcessWord(input, inOff); ProcessWord(input, inOff);
inOff += XBuf.Length; inOff += _xBuffer.Length;
length -= XBuf.Length; inLen -= _xBuffer.Length;
ByteCount += XBuf.Length; _byteCount += _xBuffer.Length;
} }
while (length > 0) while (inLen > 0)
{ {
Update(input[inOff]); Update(input[inOff]);
inOff++; inOff++;
length--; inLen--;
} }
} }
public void Finish() public void BlockUpdate(ReadOnlySpan<byte> input)
{ {
long bitLength = (ByteCount << 3); BlockUpdate(input.ToArray(), 0, input.Length);
}
Update(unchecked((byte)128)); public abstract int DoFinal(byte[] output, int outOff);
while (XBufOff != 0) Update(unchecked((byte)0)); public virtual int DoFinal(Span<byte> output)
ProcessLength(bitLength); {
ProcessBlock(); return DoFinal(output.ToArray(), 0);
} }
public virtual void Reset() public virtual void Reset()
{ {
ByteCount = 0; _byteCount = 0;
XBufOff = 0; _xBufferOff = 0;
Array.Clear(XBuf, 0, XBuf.Length); Array.Clear(_xBuffer, 0, _xBuffer.Length);
} }
public int GetByteLength() public void Finish()
{ {
return ByteLength; long bitLength = (_byteCount << 3);
Update(unchecked((byte)128));
while (_xBufferOff != 0)
Update(unchecked((byte)0));
ProcessLength(bitLength);
ProcessBlock();
} }
internal abstract void ProcessWord(byte[] input, int inOff); protected abstract void ProcessWord(byte[] input, int inOff);
internal abstract void ProcessLength(long bitLength); protected abstract void ProcessLength(long bitLen);
internal abstract void ProcessBlock(); protected abstract void ProcessBlock();
public abstract int GetDigestSize();
public abstract int DoFinal(byte[] output, int outOff);
} }
internal sealed class SM3Digest : GeneralDigest internal sealed class SM3Digest : GeneralDigest
@@ -241,6 +254,22 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
return ((x & y) | (~x & z)); return ((x & y) | (~x & z));
} }
public override int GetDigestSize()
{
return DIGEST_LENGTH;
}
public override int DoFinal(byte[] output, int outOff)
{
Finish();
for (int i = 0; i < 8; i++)
{
ConvertIntegerToBigEndian(_v1[i], output, outOff + i * 4);
}
Reset();
return DIGEST_LENGTH;
}
public override void Reset() public override void Reset()
{ {
base.Reset(); base.Reset();
@@ -251,7 +280,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
Array.Copy(X0, 0, _x, 0, X0.Length); Array.Copy(X0, 0, _x, 0, X0.Length);
} }
internal override void ProcessWord(byte[] input, int inOff) protected override void ProcessWord(byte[] input, int inOff)
{ {
int n = input[inOff] << 24; int n = input[inOff] << 24;
n |= (input[++inOff] & 0xff) << 16; n |= (input[++inOff] & 0xff) << 16;
@@ -265,18 +294,18 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
} }
} }
internal override void ProcessLength(long bitLength) protected override void ProcessLength(long bitLen)
{ {
if (_xOff > 14) if (_xOff > 14)
{ {
ProcessBlock(); ProcessBlock();
} }
_x[14] = (int)(BitOperator.URShift(bitLength, 32)); _x[14] = (int)(BitOperator.URShift(bitLen, 32));
_x[15] = (int)(bitLength & unchecked((int)0xffffffff)); _x[15] = (int)(bitLen & unchecked((int)0xffffffff));
} }
internal override void ProcessBlock() protected override void ProcessBlock()
{ {
int j; int j;
@@ -348,22 +377,6 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
_xOff = 0; _xOff = 0;
Array.Copy(X0, 0, _x, 0, X0.Length); Array.Copy(X0, 0, _x, 0, X0.Length);
} }
public override int GetDigestSize()
{
return DIGEST_LENGTH;
}
public override int DoFinal(byte[] output, int outOff)
{
Finish();
for (int i = 0; i < 8; i++)
{
ConvertIntegerToBigEndian(_v1[i], output, outOff + i * 4);
}
Reset();
return DIGEST_LENGTH;
}
} }
} }
} }