Редактировать: я исправил кодировку ascii, как указано @ DavidG
. Я создаю интеграцию с поставщиком, и интеграция требует, чтобы я подписал сообщение с помощью алгоритма HMAC-SHA256.
Простой тест, который я получил от поставщика, заключается в том, что мы собираемся использовать эти данные:
key: "1234567890ABCDEF1234567890ABCDEF" (hex)
data: "00000000" (ascii)
expected output (only first 32 chars): FF365893D899291C3BF505FB3175E880 (hex)
Я проверил несколько онлайн-генераторов hmac и нашел их длявозвращайте разные результаты для меня, некоторые правильные и некоторые неправильные.
Correct reply: https://www.liavaag.org/English/SHA-Generator/HMAC/
Correct reply: https://cryptii.com/pipes/hmac
Incorrect reply: https://codebeautify.org/hmac-generator
Incorrect reply: http://billatnapier.com/security01.aspx
Кто-нибудь может мне помочь или указать мне правильное направление здесь?Это заставляет меня очень скоро стать лысым ...
[TestClass()]
public class AutogiroConcentFileWriterTests
{
[TestMethod()]
public void ManualKVVTest()
{
String key = "1234567890ABCDEF1234567890ABCDEF";
String message = "00000000";
String expected = "FF365893D899291C3BF505FB3175E880";
Encoding ascii = Encoding.ASCII;
Byte[] key_bytes = this.KeyData(key);
Byte[] message_bytes = ascii.GetBytes(message);
System.Security.Cryptography.HMACSHA256 hmacSHA256 = new System.Security.Cryptography.HMACSHA256(key_bytes);
Byte[] hash = hmacSHA256.ComputeHash(message_bytes);
String data = this.ByteToString(hash);
// only compare first 32 chars of the hash
Assert.AreEqual(expected, data.Substring(0, 32));
//Assert.AreEqual failed.
//Expected:<FF365893D899291C3BF505FB3175E880>.
//Actual:<997BBD8C79F0D98FCA6470723CDB65D3>.
}
private Byte[] KeyData(String key)
{
if (key.Length % 2 == 1)
throw new Exception("The binary key cannot have an odd number of digits");
byte[] arr = new byte[key.Length >> 1];
Int32 pos = 0;
for (int i = 0; i < key.Length; i += 2)
{
Int32 b1 = key[i] - (key[i] < 58 ? 48 : 55);
Int32 b2 = key[i + 1] - (key[i + 1] < 58 ? 48 : 55);
arr[pos++] = (byte)((b1 << 4) + b2);
}
return arr;
}
private String ByteToString(Byte[] buff)
{
Char[] retval = new char[buff.Length * 2];
for (int i = 0; i < buff.Length; i++)
{
String t = buff[i].ToString("X2");
retval[i * 2] = t[0];
retval[i * 2 + 1] = t[1];
}
return new String(retval);
}
}