请用C#帮我解答
服务端api签名
https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/getting_started/api_signature.html
这是微信的网址。
这是我访JAVA的成功网址
https://developers.weixin.qq.com/community/develop/article/doc/000e68b8038ed8796f00f6c2f68c13
public static string RSASignPEM(string data, string privateKeyPEM, string hashAlgorithm = "MD5", string encoding = "UTF-8")
{
byte[] pemkey = Convert.FromBase64String(privateKeyPEM);
RSACryptoServiceProvider RSA = DecodeRSAPrivateKey(privateKeyPEM);//function to parse .pem file
RSAParameters rsaParams = RSA.ExportParameters(true);
RSACng RSACng = new RSACng();
RSACng.ImportParameters(rsaParams);
var dataBytes = Encoding.GetEncoding(encoding).GetBytes(data);
byte[] signature = RSACng.SignData(dataBytes, HashAlgorithmName.SHA256,RSASignaturePadding.Pss);
return Convert.ToBase64String(signature);
}
/// <summary>
/// RSA私钥格式转换
/// </summary>
/// <param name="privateKey"></param>
/// <returns></returns>
private static RSACryptoServiceProvider DecodeRSAPrivateKey(string privateKey)
{
var privateKeyBits = System.Convert.FromBase64String(privateKey);
var RSA = new RSACryptoServiceProvider();
var RSAparams = new RSAParameters();
using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits)))
{
byte bt = 0;
ushort twobytes = 0;
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130)
binr.ReadByte();
else if (twobytes == 0x8230)
binr.ReadInt16();
else
throw new Exception("Unexpected value read binr.ReadUInt16()");
twobytes = binr.ReadUInt16();
if (twobytes != 0x0102)
throw new Exception("Unexpected version");
bt = binr.ReadByte();
if (bt != 0x00)
throw new Exception("Unexpected value read binr.ReadByte()");
RSAparams.Modulus = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.Exponent = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.D = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.P = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.Q = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.DP = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.DQ = binr.ReadBytes(GetIntegerSize(binr));
RSAparams.InverseQ = binr.ReadBytes(GetIntegerSize(binr));
}
RSA.ImportParameters(RSAparams);
return RSA;
}
private static int GetIntegerSize(BinaryReader binr)
{
byte bt = 0;
byte lowbyte = 0x00;
byte highbyte = 0x00;
int count = 0;
bt = binr.ReadByte();
if (bt != 0x02)
return 0;
bt = binr.ReadByte();
if (bt == 0x81)
count = binr.ReadByte();
else
if (bt == 0x82)
{
highbyte = binr.ReadByte();
lowbyte = binr.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = bt;
}
while (binr.ReadByte() == 0x00)
{
count -= 1;
}
binr.BaseStream.Seek(-1, SeekOrigin.Current);
return count;
}
C#,这是签名方法,签名后一直提示签名错误
这是调用签名代码
String url_path = ctx["url_path"].ToString();
int reqTs = req["req_ts"].ObjectToInt();
String reqData = req["req_data"].ToString();
String payload = url_path + "\n" + local_appid + "\n" + reqTs + "\n" + reqData;
RSASignPEM(payload, local_private_key); //这里证书用的是直接下载的证书,一直提示签名错误,也不知道哪里出错了。
var apiUrl = $"{url_path}?access_token={token}"
.WithHeader("Content-Type", "application/json;charset=utf-8")
.WithHeader("Wechatmp-Appid", local_appid)
.WithHeader("Wechatmp-TimeStamp", localTs)
.WithHeader("Wechatmp-Signature", sign)
;
var result = await apiUrl.PostJsonAsync(reqData).ReceiveJson<JObject>();
POST返回一直提示签名出错