【问题标题】:C# version of the javascript function Cryptojs.HmacSHA384C# 版本的 javascript 函数 Cryptojs.HmacSHA384
【发布时间】:2020-07-21 14:32:46
【问题描述】:

我正在尝试连接到我需要通过在我的 C# 应用程序中的标头中传递一个散列字符串来进行身份验证的 API。在提供者的文档中,虽然他们只有一个如何在反应应用程序中使用 JS 函数对字符串进行哈希处理的示例,但下面是在所述文档中找到的代码 sn-p 的屏幕截图。

我已经找到一篇关于 btoa 函数替代方案的文章 here on stackoverflow,但我完全坚持使用 CryptoJS.HmacSHA384 函数替代方案。我曾尝试使用 System.Security.Cryptography.HMACSHA384 类,但无法弄清楚如何对我传递给该方法的字符串进行编码以获得相同的结果,导致当我尝试连接到 API 时授权被拒绝端点。贝娄是我迄今为止编写的方法的代码(那是行不通的):

    public void myMethodToConnet(string user, string pass, string custId, string partId, string partKey, string ver, string commId)
{
    int resetPasswordErrorCode;

    _user = user;
    _password = pass;
    _rooftopId = custId;
    _partnerId = partId;
    _partnerKey = Encoding.UTF8.GetBytes(partKey);
    _version = ver;
    _communityId = commId;

    _url = "url";

    _token = GetToken().Result;

    using (HMACSHA384 hmac = new HMACSHA384(_partnerKey))
    {
        _hmac = hmac.ComputeHash(Encoding.UTF8.GetBytes(_token));

        _hash = BTOA($"{_user}:{Encoding.UTF8.GetString(_hmac)}:{_password}");
    }
    ActivateToken().Result;
}
private static string BTOA(string toEncode)
{
    byte[] bytes = Encoding.GetEncoding(28591).GetBytes(toEncode);
    string result = System.Convert.ToBase64String(bytes);
    return result;
}
private async Task<int> ActivateToken()
{
    CheckPasswordRequest request = new CheckPasswordRequest();
    CheckPasswordResponse response = new CheckPasswordResponse();
    StringContent content;
    string jsonString;
    string apiResponse;
    int errorCode = 0;

    using (HttpClient httpClient = new HttpClient())
    {
        request = new CheckPasswordRequest() { RooftopId = _rooftopId };
        jsonString = JsonConvert.SerializeObject(request);
        content = new StringContent(jsonString, Encoding.UTF8, "application/json");
        httpClient.DefaultRequestHeaders.Add("Authorization", $"DataHub-Hash {_hash}");
        using (var resp = await httpClient.PostAsync($"{_url}/CheckPassword", content))
        {
            apiResponse = await resp.Content.ReadAsStringAsync();
            response = JsonConvert.DeserializeObject<CheckPasswordResponse>(apiResponse);
            errorCode = response.ErrorCode;
        }
    }
    return errorCode;
}

谢谢!

【问题讨论】:

  • 你确定你得到了_partnerKey的正确字节并将正确的字符串传递给BTOA吗?我是在不了解您的系统的情况下这么说的,但Encoding.UTF8.GetBytes 似乎是获取密钥的一种奇怪方式。我希望 partKey 是 Base64 字符串或十六进制字符串。与您编码_hmac 的方式相同。我希望您需要将其转换为 Base64 或十六进制。
  • 我终于弄明白了,关键是实际上是正确的,问题出在 _hmac 中,对于这种特定情况需要使用十六进制。一旦我从我添加的各种测试 sn-ps 中清理了所有内容,我会写一个完整的解释我做了什么!

标签: c# .net-core header authorization cryptojs


【解决方案1】:

我最终通过创建一个简单的 HTML 页面来解决这个问题,我在其中运行 JS 命令并打印输出,然后将其与我的 C# 应用程序中的输出进行比较。最后的解决方案是将加密算法的字节数组输出转换为十六进制,为此我创建了这个辅助方法:

public static string ByteToString(byte[] input)
{
    string output= "";

    for (int i = 0; i < input.Length; i++)
    {
        output+= input[i].ToString("X2");
    }
    return (output);
}  

通过在用户和密码之间插入此方法的输出字符串并运行我的 BTOA 辅助方法,返回 API 期望的字符串并设法进行身份验证。

【讨论】:

    猜你喜欢
    • 2018-02-16
    • 1970-01-01
    • 2011-12-29
    • 2013-06-19
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    相关资源
    最近更新 更多