Search code examples
pythonprotocol-buffersdecodeencode

unable to deserialize protobuf bytes field in python


I'm passing using protobuf an hashed byte array. but while trying to deserialize it, I'm getting the following error:

'utf-8' codec can't decode byte 0xd6 in position 1: 'utf-8' codec can't decode byte 0xd6 in position 1: invalid continuation byte in field: master.hash1

the code is simply:

a = message.ParseFromString(data)

I believe it is a simple matter of encoding\decoding, but I have no idea how to do so.

This is the code to encode the data in c#:

public byte[] HmacSign(string key, string message)
{
    var encoding = new System.Text.ASCIIEncoding();
    byte[] keyByte = encoding.GetBytes(key);

    HMACSHA1 hmacsha1 = new HMACSHA1(keyByte);

    byte[] messageBytes = encoding.GetBytes(message);
    byte[] hashmessage = hmacsha1.ComputeHash(messageBytes);

    return hashmessage;
}

Solution

  • You are using ASCII to encode your data so you have to use ASCII also to decode:

    s = str(data, 'ascii')
    message.ParseFromString(s)
    

    If you prefer to use UTF-8, then change the encoding of your c# code:

    public byte[] HmacSign(string key, string message)
    {
        var encoding = new System.Text.UTF8Encoding();
        byte[] keyByte = encoding.GetBytes(key);
    
        HMACSHA1 hmacsha1 = new HMACSHA1(keyByte);
    
        byte[] messageBytes = encoding.GetBytes(message);
    
        byte[] hashmessage = hmacsha1.ComputeHash(messageBytes);
        return hashmessage;
    }
    

    And then use UTF-8 in your python code:

    s = str(data, 'utf-8')
    message.ParseFromString(s)
    

    EDIT

    If still not working, try to return a string from your c# code:

    public string HmacSign(string key, string message)
    {
        var encoding = new System.Text.UTF8Encoding();
        byte[] keyByte = encoding.GetBytes(key);
        byte[] messageBytes = encoding.GetBytes(message);
        using (var hmacsha new HMACSHA1(keyByte))
        {
            byte[] hashmessage = hmacsha.ComputeHash(messageBytes);
            return Convert.ToBase64String(hashmessage);
        }
    }
    

    And in your Python code:

    import base64
    s = base64.b64decode(data).decode('utf-8')
    message.ParseFromString(s)