C# C语言中的RSA SHA256 http签名#

C# C语言中的RSA SHA256 http签名#,c#,http,rsa,signature,sha256,C#,Http,Rsa,Signature,Sha256,我试图在API中实现http签名,以连接到EWP网络(无纸伊拉斯谟)。我有一个关于工作数据的示例,我正在尝试使用该数据进行测试,但我无法验证http签名 使用请求中的keyId,我从另一个API检索公钥 下面是我从这个例子中得到的: Header: Authorization: Signature keyId="2bc25340265c0331632c2bc7d82cabdf3a6ebba0a8cc6435b401d62dd2c7daea",signature="d

我试图在API中实现http签名,以连接到EWP网络(无纸伊拉斯谟)。我有一个关于工作数据的示例,我正在尝试使用该数据进行测试,但我无法验证http签名

使用请求中的keyId,我从另一个API检索公钥

下面是我从这个例子中得到的:

Header:
Authorization: Signature keyId="2bc25340265c0331632c2bc7d82cabdf3a6ebba0a8cc6435b401d62dd2c7daea",signature="dlpL2OjVMZi4bqFnVtvc8Z6qqOvdmb6g/P42PQrP6w5+/mxF1S9COx7CkRAMi+6KdH0XGdgT4G0Vi85VVI7vSoYgvVCSgBeyFyfP7HwYROEhd1QgM9VgV001wXvDNJbvTOXh2S+1IAP/8YwIM3RQOg64ZRJEMUEWf91VczjTXC9sElGK4jP0AAbsg727cE/b8LeOH25vl6tzyypDFaCCA3MAgdF2+fNdNG9gr0OKa5ia7Dums1aXKmcqhOaWTiiS7vTYhnwBS7BlQMnrDF6kOtVQomVDB11vfEKvmgkXIXxRvpHMTG6+7F32DCu3imS2wIjJccQSglyFFJ4/qjnNKA==",headers="(request-target) date digest host x-request-id",algorithm="rsa-sha256"
Date: Fri, 30 Oct 2020 14:19:18 GMT
Digest: "SHA-256=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="
Host: "sga-mobilidadenet.ua.pt"
X-Request-Id: "76092379-75d1-462d-b7b7-af6a87b000bd"

Url used is sga-mobilidadenet.ua.pt/mobilidadenet/ewp/ewpstage/echo?echo=a&echo=b&echo=a
我从另一个API获得的公钥是

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA67WEK5VlMUFC0wdLmTV4TyeDwA1U4NV5GvL/x29ujKY0/tWSoqwRPvIyhQ6h2M3MQpaLIb4PQsRzh299KaCNQ799+0HH7KMTZMN5AwoSw4y5RS6ImhlwRm4N4yDoekQgQuXTaPLEfYBURPrTJ8/V2Wb6yW8LgfPknESNglRkprhFKOoWJzlv00rzCO7QZSdXh5LYU0TYOlj+WrfoCM8xODOQqCJsnS7grY7YNtR08qB2fo7UEYXrUw8aoe5ZZZeKv1b5M1+ZDR1aAHZRhMbPyp7JIRxW5fAT/ZDxUHv8lfOksgnF+AXHSGFdvteEbSJHrfOnMiUScBil306/VeSVXQIDAQAB
(用空格和线刹车,但我过滤掉了?)

在我的API中,我需要做的是检查授权头中的签名是否正确,以及摘要是否是正确的哈希

我用来测试的代码如下:

private void test()
        {
            //(request-target) date digest host x-request-id
            string dataForSign = "(request-target): " + "get /mobilidadenet/ewp/ewpstage/echo?echo=a&echo=b&echo=a" + "\n" ;
            dataForSign += "date: " + "Fri, 30 Oct 2020 14:19:18 GMT" + "\n";
            dataForSign += "digest: " + "SHA-256=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=" + "\n";
            dataForSign += "host: " + "sga-mobilidadenet.ua.pt" + "\n";
            dataForSign += "x-request-id: " + "76092379-75d1-462d-b7b7-af6a87b000bd";
            
            string signature = "dlpL2OjVMZi4bqFnVtvc8Z6qqOvdmb6g/P42PQrP6w5+/mxF1S9COx7CkRAMi+6KdH0XGdgT4G0Vi85VVI7vSoYgvVCSgBeyFyfP7HwYROEhd1QgM9VgV001wXvDNJbvTOXh2S+1IAP/8YwIM3RQOg64ZRJEMUEWf91VczjTXC9sElGK4jP0AAbsg727cE/b8LeOH25vl6tzyypDFaCCA3MAgdF2+fNdNG9gr0OKa5ia7Dums1aXKmcqhOaWTiiS7vTYhnwBS7BlQMnrDF6kOtVQomVDB11vfEKvmgkXIXxRvpHMTG6+7F32DCu3imS2wIjJccQSglyFFJ4/qjnNKA==";
            
            string publicKey =
                "<RSAKeyValue><Modulus>MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA67WEK5VlMUFC0wdLmTV4TyeDwA1U4NV5GvL/x29ujKY0/tWSoqwRPvIyhQ6h2M3MQpaLIb4PQsRzh299KaCNQ799+0HH7KMTZMN5AwoSw4y5RS6ImhlwRm4N4yDoekQgQuXTaPLEfYBURPrTJ8/V2Wb6yW8LgfPknESNglRkprhFKOoWJzlv00rzCO7QZSdXh5LYU0TYOlj+WrfoCM8xODOQqCJsnS7grY7YNtR08qB2fo7UEYXrUw8aoe5ZZZeKv1b5M1+ZDR1aAHZRhMbPyp7JIRxW5fAT/ZDxUHv8lfOksgnF+AXHSGFdvteEbSJHrfOnMiUScBil306/VeSVXQIDAQAB</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

            
            byte[] dataForSignAsBytes = Encoding.UTF8.GetBytes(dataForSign);
            byte[] signatureEncoded = Convert.FromBase64String(signature);

            RSACryptoServiceProvider rsaCryptoServiceProvider = new RSACryptoServiceProvider();
            rsaCryptoServiceProvider.FromXmlString(publicKey);

            var hashData = SHA256.Create().ComputeHash(dataForSignAsBytes);

            var result1 = rsaCryptoServiceProvider.VerifyData(dataForSignAsBytes, CryptoConfig.MapNameToOID("SHA256"), signatureEncoded);
            var result2 = rsaCryptoServiceProvider.VerifyHash(hashData, CryptoConfig.MapNameToOID("SHA256"), signatureEncoded);
            Console.WriteLine(result1);
            Console.WriteLine(result2);
        }
private void test()
{
//(请求目标)日期摘要主机x-request-id
字符串dataForSign=“(请求目标):“+”get/mobilidadenet/ewp/ewpstage/echo?echo=a&echo=b&echo=a“+”\n”;
dataForSign+=“日期:”+“2020年10月30日星期五14:19:18 GMT”+“\n”;
dataForSign+=“digest:”+“SHA-256=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=“+”\n”;
dataForSign+=“主机:”+“sga mobilidadenet.ua.pt”+“\n”;
dataForSign+=“x-request-id:”+“76092379-75d1-462d-b7b7-af6a87b000bd”;
字符串签名=4.这两个词的意思是:一个词的意思意思是:一个词的意思是:一个词的意思是,一个词的意思是,一个词的意思是:一个词的意思是,一个vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvLYFFJ4/qjnNKA==”;
字符串公钥=
"在中国,这是一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在中国的一个在一个中国的一个在一个非非非中国的非非非非中国的非中国的非中国的非中国的非中国的非中国的非中国的非中国的非中国的非中国的非中国的非中国的非中国非中国的非中国非中国的非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非中国非YP7JIRXW5FAT/ZDxUHv8lfOksgnF+AXHSGFdvteEbSJHrfOnMiUScBil306/VeSVXQIDAQABAQAB”;
byte[]dataForSignAsBytes=Encoding.UTF8.GetBytes(dataForSign);
字节[]signatureEncoded=Convert.FromBase64String(签名);
RSACryptoServiceProvider RSACryptoServiceProvider=新的RSACryptoServiceProvider();
rsacyptoserviceprovider.FromXmlString(公钥);
var hashData=SHA256.Create().ComputeHash(dataForSignAsBytes);
var result1=rsacryptserviceprovider.VerifyData(dataForSignAsBytes,CryptoConfig.MapNameToOID(“SHA256”),signatureEncoded);
var result2=rsacryptserviceprovider.VerifyHash(hashData,CryptoConfig.MapNameToOID(“SHA256”),signatureEncoded);
控制台写入线(结果1);
控制台写入线(结果2);
}
这两个结果都是错误的


我真的被这个问题困扰着,觉得我离解决方案只有几步之遥,但只要它不起作用,我就被困在这里……任何帮助都将不胜感激,因为我没有http签名或RSA-SHA256的经验……

您确定您使用的是与另一方相同的配方来生成签名吗?请注意要使签名匹配,两侧的ata必须完全相同。在您的示例中,请求已大写了标头名称,而您尝试验证的数据使用小写标头名称。单个不同的字符将完全更改签名,因此请确保数据字符串中没有任何更改。您应该遵循计算签名的hole算法-据我所知,EWP使用-注意签名包含整个HTTP消息-内容,所有标题等。是的,看看@Luaan在说什么,我不认为你捕获的严格来说是整个HTTP有效载荷。你能使用burp/charles/fiddler捕获原始有效载荷吗?谢谢r响应。我得到的示例来自在线开发环境,在该环境中,测试请求可以发送到联机的API。我的ins尚未联机,因此我无法捕获任何内容。我只是使用了我发现测试正在使用的数据,并尝试测试是否可以验证它。我使用了小写的头名称,正如aut中使用的头名称一样horization header:headers=“(请求目标)日期摘要主机x-request-id”这难道不意味着这些是我创建签名字符串(我的代码中的dataForSign)所需的唯一标题吗?如果有人真的想在这方面投入时间,可以在.XPath函数上找到注册表来查找公钥:``XmlDocument doc=new XmlDocument();doc.Load(path);var nsm=newXMLNamespaceManager(doc.NameTable);nsm.AddNamespace(“r”,”);XmlNode root=doc.DocumentElement;var XPathExpr=@”//r:binaries/r:rsa公钥[@sha-256=“”+keyId+@“”];clientPublicKey=root.SelectSingleNode(XPathExpr,namespaceManager)```您确定使用与另一方相同的配方生成签名吗?请注意,双方的数据必须完全相同,签名才能匹配。在您的示例中,请求使用大写的头名称,而您尝试验证的数据使用小写的头名称。一个不同的字符将完全更改签名,因此请确保数据字符串中没有任何更改。你应该遵循计算签名的整个算法-据我所知,EWP使用-注意签名包含整个HTTP消息-内容,所有标题等。是的,看看@Luaan在说什么,我不认为你捕获的严格来说是整个HTTP负载。你能用burp/charles/fiddler捕捉原始有效载荷吗?谢谢你的回复。我得到的例子来自在线开发环境,在那里测试请求可以发送到在线的API。我的ins还没有上线,所以我还不能用它捕获任何东西。我只是使用了我发现测试使用的数据和t