Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/278.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 比较JSON对象的哈希_C#_Json_Api_Hash_.net Core - Fatal编程技术网

C# 比较JSON对象的哈希

C# 比较JSON对象的哈希,c#,json,api,hash,.net-core,C#,Json,Api,Hash,.net Core,我正在尝试让哈希比较器工作,以便验证传入的请求 流量: 发送方创建json对象->发送方使用他们和我都知道的密钥创建json对象的散列->发送方发送json对象和包含散列的头->我收到请求->我使用公共密钥散列json对象->我将我的散列与头中的散列进行比较以验证用户发送它 我正在努力从json对象创建哈希 这是Ruby中的示例代码(来自发送方),其中request\u payload是JSON对象 hmac=OpenSSL::HMAC.digest(OpenSSL::Digest.new('s

我正在尝试让哈希比较器工作,以便验证传入的请求

流量:
发送方创建json对象
->
发送方使用他们和我都知道的密钥创建json对象的散列
->
发送方发送json对象和包含散列的头
->
我收到请求
->
我使用公共密钥散列json对象
->
我将我的散列与头中的散列进行比较以验证用户发送它

我正在努力从json对象创建哈希

这是Ruby中的示例代码(来自发送方),其中
request\u payload
是JSON对象

hmac=OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'),YOUR_COMPANY_SIGNING_KEY,request_payload)  
signature = Base64.strict_encode64(hmac)
我想用C#来做这个

我正在使用来自(见右侧)的数据,并尝试将其散列为字符串,然后对其进行编码

[HttpPost]
public async Task<ActionResult> PostAsync(dynamic request)
{

    string signature = GetHash(request.ToString(), "072e77e426f92738a72fe23c4d1953b4"); // this key is from the example in Call Rail

    string encodedSignature = Base64Encode(signature);

    return Ok();
}

public static String GetHash(dynamic text, String key)
{
    ASCIIEncoding encoding = new ASCIIEncoding();

    Byte[] textBytes = encoding.GetBytes(text);
    Byte[] keyBytes = encoding.GetBytes(key);

    Byte[] hashBytes;

    using (HMACSHA1 hash = new HMACSHA1(keyBytes))
        hashBytes = hash.ComputeHash(textBytes);

    return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
}

public static string Base64Encode(string plainText)
{
    var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
    return System.Convert.ToBase64String(plainTextBytes);
}
然后把它分解成有用的东西

使用给定的测试签名密钥,我应该返回
UZAHbUdfm3GqL7qzilGozGzWV64=
。我从报纸上知道这一点

我目前正在通过邮递员发送上面的JSON字符串,但我注意到,当我将其视为数据类型
动态
对象
时,会添加额外的“
{


如有任何见解,将不胜感激

我认为您面临的问题是.NET核心WebAPI正在帮助您将主体解析为JSON(转换为
JObject

正如@dbc所指出的,您真正需要的是用于生成HMAC签名的原始字符串主体,您可以在自己将主体解析为JSON之前进行验证

我进行了测试,能够以普通字符串的形式接收尸体:

使用系统;
使用System.Linq;
使用System.Threading.Tasks;
使用System.IO;
使用Microsoft.AspNetCore.Mvc.Formatters;
名称空间netcoretest{
公共类RawJsonBodyInputFormatter:InputFormatter
{
公共RawJsonBodyInputFormatter()
{
this.SupportedMediaTypes.Add(“application/json”);
}
公共重写异步任务ReadRequestBodyAsync(InputFormatterContext上下文)
{
var request=context.HttpContext.request;
使用(var reader=newstreamreader(request.Body))
{
var content=wait reader.ReadToEndAsync();
返回等待InputFormatterResult.SuccessAsync(内容);
}
}
受保护的覆盖布尔CanReadType(类型)
{
返回类型==typeof(字符串);
}
}
}
Startup.cs:

//在ConfigureServices()中
services.AddMvc(选项=>{
Insert(0,新的RawJsonBodyInputFormatter());
});
在控制器中:

[HttpPost]
public async Task<ActionResult> PostTest([FromBody]string request)
{
  // here request is now the request body as a plain string;
  // you can now compute the signature on it and then later parse it to JSON.


}
[ValidateCallRailRequestFilter]
[HttpPost]
public async Task<ActionResult> PostAsync(dynamic request)
{
    ...
    return Ok();
}
因此,至少这一部分也需要在您的实现中进行更正

更新

我能够使用以下代码获得正确的签名:

使用Microsoft.AspNetCore.Mvc;
使用Microsoft.EntityFrameworkCore;
使用System.Collections.Generic;
使用System.Linq;
使用System.Threading.Tasks;
使用制度;
使用System.Security.Cryptography;
使用系统文本;
命名空间netcoretest.Controllers
{
[路线(“测试”)]
[ApiController]
公共类TestController:ControllerBase
{
公共测试控制器()
{
}
//后:/test
[HttpPost]
公共异步任务PostTest([FromBody]字符串请求)
{
ascienceoding encoding=新的ascienceoding();
Byte[]key=encoding.GetBytes(“072e77e426f92738a72fe23c4d1953b4”);
HMACSHA1 hmac=新的HMACSHA1(键);
Byte[]bytes=hmac.ComputeHash(encoding.GetBytes(request));
WriteLine(ByteArrayToString(字节));
字符串结果=System.Convert.ToBase64String(字节);
控制台写入线(结果);
返回Ok();
}
公共静态字符串ByteArrayToString(字节[]ba)
{
返回BitConverter.ToString(ba).替换(“-”,”);
}
}
}
我使用以下方法测试了发布到此端点:

url --request POST https://localhost:5001/test --insecure --header 'Content-Type: application/json' --data-binary @test.json
其中
test.json
是API文档中的json blob示例

如果使用相同的代码无法获得匹配的签名,请仔细检查
test.json
是否没有任何尾随的换行符或空格


希望这有帮助

我认为您面临的问题是.NET核心WebAPI正在帮助您将主体解析为JSON(转换为
JObject

正如@dbc所指出的,您真正需要的是用于生成HMAC签名的原始字符串主体,您可以在自己将主体解析为JSON之前进行验证

我进行了测试,能够以普通字符串的形式接收尸体:

使用系统;
使用System.Linq;
使用System.Threading.Tasks;
使用System.IO;
使用Microsoft.AspNetCore.Mvc.Formatters;
名称空间netcoretest{
公共类RawJsonBodyInputFormatter:InputFormatter
{
公共RawJsonBodyInputFormatter()
{
this.SupportedMediaTypes.Add(“application/json”);
}
公共重写异步任务ReadRequestBodyAsync(InputFormatterContext上下文)
{
var request=context.HttpContext.request;
使用(var reader=newstreamreader(request.Body))
{
var content=wait reader.ReadToEndAsync();
返回等待InputFormatterResult.SuccessAsync(内容);
}
}
受保护的覆盖布尔CanReadType(类型)
{
返回类型==typeof(字符串);
}
}
}
Startup.cs:

//在ConfigureServices()中
services.AddMvc(选项=>{
Insert(0,新的RawJsonBodyInputFormatter());
});
在控制器中:

[HttpPost]
public async Task<ActionResult> PostTest([FromBody]string request)
{
  // here request is now the request body as a plain string;
  // you can now compute the signature on it and then later parse it to JSON.


}
[ValidateCallRailRequestFilter]
[HttpPost]
public async Task<ActionResult> PostAsync(dynamic request)
{
    ...
    return Ok();
}
因此,至少这一部分也需要在您的实现中进行更正

更新