pythonc#hmachmacsha256

Problem with recreating python b64encode and hmac function in C#


I have to create a function that generates exactly the same signature as it does in python. Here is my code

 if __name__ == '__main__':
    client_secret = 'aasfeef422c2dsa84fe9e7f56e6f214b'
    client_key_id = 'PHFg6w5XwnIYasDvdkqSjA=='
    nonce = 'fb807056-0d41-4c55-aa65-598a600bfe49'
    timestamp = '2022-04-01T06:57:50.280Z'

    signature = b64encode(hmac.new(b64decode(client_secret), msg=bytes(client_key_id + nonce + timestamp, 'utf-8'),
                                   digestmod=hashlib.sha256).digest()).decode('utf-8')

value of signature here is: 'eenCmMzL12aPGat2zouBCaQQh9dC+8mJsm1KNpYQmOs='

I have written down a C# function and the code looks like this:

        private static string Base64Encode(string text)
        {
            var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(text);
            return System.Convert.ToBase64String(plainTextBytes);
        }

        private static string GetHMAC(string text, string key)
        {
            key = key ?? "";

            using (var hmacsha256 = new HMACSHA256(Encoding.UTF8.GetBytes(key)))
            {
                var hash = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(text));
                return Convert.ToBase64String(hash);
            }
        }

        public static void Main(string[] args)
        {
            var client_secret = "aasfeef422c2dsa84fe9e7f56e6f214b";
            var client_key_id = "PHFg6w5XwnIYasDvdkqSjA==";
            var nonce = "fb807056-0d41-4c55-aa65-598a600bfe49";
            var timestamp = "2022-04-01T06:57:50.280Z";

            var hmac = GetHMAC(client_key_id + nonce + timestamp, Base64Encode(client_secret));
            var signature = Base64Encode(hmac);   
        }

unfortunately here the value of signature is "dklPYzdlOEhjS1pZaU1UdkYweWRGZTRhZkFvUEF6djhiMUxpMFZOL2x1Yz0="

and this is a huge difference. Do you have any idea how I can fix that problem, and make the C# algorithm generate the same signature, as the python algorithm ?


Solution

  • There are a lot of issues with your C# code, including performing repeated Base64 encodings of the same data. The correct code is relatively simple:

    private static string GetHMAC(string text, byte[] key)
    {
        using (var hmacsha256 = new HMACSHA256(key))
        {
            var hash = hmacsha256.ComputeHash(Encoding.UTF8.GetBytes(text));
            return Convert.ToBase64String(hash);
        }
    }
    
    public static void Main(string[] args)
    {
        var client_secret = "aasfeef422c2dsa84fe9e7f56e6f214b";
        var client_key_id = "PHFg6w5XwnIYasDvdkqSjA==";
        var nonce = "fb807056-0d41-4c55-aa65-598a600bfe49";
        var timestamp = "2022-04-01T06:57:50.280Z";
    
        var hmac = GetHMAC(client_key_id + nonce + timestamp, Convert.FromBase64String(client_secret));
        Console.WriteLine(hmac);
    }
    

    This outputs eenCmMzL12aPGat2zouBCaQQh9dC+8mJsm1KNpYQmOs= as expected