簡體   English   中英

c# Base64 編碼解碼錯誤結果

[英]c# Base64 Encoding Decoding wrong result

我需要在 c# 中創建一個哈希簽名。

我需要在我的 c# 代碼中實現的偽代碼示例:

Signatur(Request) = new String(encodeBase64URLCompatible(HMAC-SHA-256(getBytes(Z, "UTF-8"), decodeBase64URLCompatible(getBytes(S, "UTF-8")))), "UTF-8")

Z:apiSecret S:stringToSign

expectedSignaturapiSecret的編碼是Base64 URL Encoding [RFC 4648 Section 5]

我的問題是我總是得到錯誤的結果。

public static string Base64Decode(string base64EncodedData)
{
    var base64EncodedBytes = Convert.FromBase64String(base64EncodedData);
    return Encoding.UTF8.GetString(base64EncodedBytes);
}

public static string Base64Encode(string plainText)
{
    var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
    return Convert.ToBase64String(plainTextBytes);
}

private static byte[] HmacSha256(string data, string key)
{
     using (var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(key)))
     {
       return hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
     }
}

static void Main(string[] args)
{
     var apiSecret = "JrXRHCnUegQJAYSJ5J6OvEuOUOpy2q2-MHPoH_IECRY=";
     var stringToSign = "f3fea5f3-60af-496f-ac3e-dbb10924e87a:20160201094942:e81d298b-60dd-4f46-9ec9-1dbc72f5b5df:Qg5f0Q3ly1Cwh5M9zcw57jwHI_HPoKbjdHLurXGpPg0yazdC6OWPpwnYi22bnB6S";
     var expectedSignatur = "ps9MooGiTeTXIkPkUWbHG4rlF3wuTJuZ9qcMe-Y41xE=";

     apiSecret = apiSecret.Replace('-', '+').Replace('_', '/').PadRight(apiSecret.Length + (4 - apiSecret.Length % 4) % 4, '=');

     var secretBase64Decoded = Base64Decode(apiSecret);

     var hmac = Convert.ToBase64String(HmacSha256(secretBase64Decoded, stringToSign));

     var signatur = hmac.Replace('+', '-').Replace('/', '_');


     Console.WriteLine($"signatur: {signatur}");
     Console.WriteLine($"expected: {expectedSignatur}");

     Console.WriteLine(signatur.Equals(expectedSignatur));
     Console.ReadLine();
 }

您假設您的密鑰最初是用 UTF-8 編碼的文本 - 但看起來並非如此。 您應該將邏輯上的二進制數據保留二進制數據 - 您根本不需要Base64EncodeBase64Decode方法。 相反,您的HmacSha256方法應該將byte[]作為鍵,您可以使用Convert.FromBase64String從 base64 編碼的秘密中獲取這些字節:

using System;
using System.Text;
using System.Security.Cryptography;

class Test
{    
    private static byte[] HmacSha256(byte[] key, string data)
    {
        using (var hmac = new HMACSHA256(key))
        {
            return hmac.ComputeHash(Encoding.UTF8.GetBytes(data));
        }
    }

    static void Main(string[] args)
    {
        var apiSecret = "JrXRHCnUegQJAYSJ5J6OvEuOUOpy2q2-MHPoH_IECRY=";
        var stringToSign = "f3fea5f3-60af-496f-ac3e-dbb10924e87a:20160201094942:e81d298b-60dd-4f46-9ec9-1dbc72f5b5df:Qg5f0Q3ly1Cwh5M9zcw57jwHI_HPoKbjdHLurXGpPg0yazdC6OWPpwnYi22bnB6S";
        var expectedSignatur = "ps9MooGiTeTXIkPkUWbHG4rlF3wuTJuZ9qcMe-Y41xE=";

        apiSecret = apiSecret.Replace('-', '+').Replace('_', '/').PadRight(apiSecret.Length + (4 - apiSecret.Length % 4) % 4, '=');

        var secretBase64Decoded = Convert.FromBase64String(apiSecret);

        var hmac = Convert.ToBase64String(HmacSha256(secretBase64Decoded, stringToSign));

        var signatur = hmac.Replace('+', '-').Replace('/', '_');
        Console.WriteLine($"signatur: {signatur}");
        Console.WriteLine($"expected: {expectedSignatur}");            
        Console.WriteLine(signatur.Equals(expectedSignatur));
    }
}

我個人HmacSha256您的HmacSha256方法更改為:

private static byte[] ComputeHmacSha256Hash(byte[] key, byte[] data)
{
    using (var hmac = new HMACSHA256(key))
    {
        return hmac.ComputeHash(data);
    }
}

以便它更通用,為了方便起見,可能會添加另一種方法來在編碼為 UTF-8 后計算散列。 這樣你就可以對任何數據進行簽名,而不僅僅是字符串。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM