I'm currently trying to figure out how to calculate the MD5 message digest for message attributes in AWS. I'm following the uri SQS message metadata > Calculating the MD5 message digest for message attributes
Although this seems straight forward I'm trying to get the hash of the following attribute
var messageAttributes = new Dictionary<string, MessageAttributeValue>
{
{"UserName", new MessageAttributeValue {DataType ="String", StringValue = "Me"}}
};
I've sent this message and the MD5 response was 3a6071d47534e3e07414fea5046fc217
Trying to figure out the documentation I thought this should have done the trick:
private void CustomCalc()
{
var verifyMessageAttributes = new List<byte>();
verifyMessageAttributes.AddRange(EncodeString("UserName"));
verifyMessageAttributes.AddRange(EncodeString("String"));
verifyMessageAttributes.AddRange(EncodeString("Me"));
var verifyMessageAttributesMd5 = GetMd5Hash(verifyMessageAttributes.ToArray());
}
private List<byte> EncodeString(string data)
{
var result = new List<byte>();
if (BitConverter.IsLittleEndian)
{
result.AddRange(BitConverter.GetBytes(data.Length).Reverse());
}
else
{
result.AddRange(BitConverter.GetBytes(data.Length));
}
result.AddRange(Encoding.UTF8.GetBytes(data));
return result;
}
public static string GetMd5Hash(byte[] input)
{
using (var md5Hash = MD5.Create())
{
// Convert the input string to a byte array and compute the hash.
var dataBytes = md5Hash.ComputeHash(input);
// Create a new string builder to collect the bytes and create a string.
var sBuilder = new StringBuilder();
// Loop through each byte of the hashed data and format each one as a hexadecimal string.
foreach (var dataByte in dataBytes)
{
sBuilder.Append(dataByte.ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
}
But I ended up with this cf886cdabbe5576c0ca9dc51871d10ae Does anyone knows where I'm going wrong. It can't be that hard I guess I just don't see it at the moment.
You are almost there but missing one step:
Encode the transport type (String or Binary) of the value (1 byte).
Note The logical data types String and Number use the String transport type.
The logical data type Binary uses the Binary transport type.
For the String transport type, encode 1.
For the Binary transport type, encode 2.
So you need to append either 1 or 2 before value, to indicate transport type. In your case:
var verifyMessageAttributes = new List<byte>();
verifyMessageAttributes.AddRange(EncodeString("UserName"));
verifyMessageAttributes.AddRange(EncodeString("String"));
verifyMessageAttributes.Add(1); // < here
verifyMessageAttributes.AddRange(EncodeString("Me"));
var verifyMessageAttributesMd5 = GetMd5Hash(verifyMessageAttributes.ToArray());