2016-10-18 4 views
2

私はC#でハッシュ署名を作成する必要があります。c#Base64エンコーディング誤った結果をデコードする

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]

私である私は私のC#コードで実装する必要があること

擬似コードの例問題は私がいつも間違った結果を得ることです。

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(); 
} 

答えて

2

あなたのキーはもともとはUTF-8でエンコードされたテキストであったとしますが、そうでなかったようです。論理的にバイナリデータをバイナリデータとして保存する必要があります。Base64EncodeBase64Decodeメソッドはまったく必要ありません。代わりに、あなたのHmacSha256方法は、キーとしてbyte[]を取る必要があり、そしてあなただけのbase64エンコード秘密から、それらのバイトで取得するためにConvert.FromBase64Stringを使用することができます。

:個人的に私はあなたの HmacSha256方法を変更したい

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)); 
    } 
} 

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

もっと一般的な目的のために、便宜上UTF-8としてエンコードした後にハッシュを計算する別の方法を追加することがあります。そうすれば、文字列だけでなく、の任意のデータに署名することができます。

関連する問題