实施修改后的 HMAC
Implementing Modified HMAC
所以我正在尝试实现 HMAC function for academic purposes. Here is the algorithm as provided by Wikipedia:
的小型修改版本
function hmac (key, message)
if (length(key) > blocksize) then
key = hash(key) // keys longer than blocksize are shortened
end if
if (length(key) < blocksize) then
// keys shorter than blocksize are zero-padded (where ∥ is concatenation)
key = key ∥ [0x00 * (blocksize - length(key))] // Where * is repetition.
end if
o_key_pad = [0x5c * blocksize] ⊕ key // Where blocksize is that of the underlying hash function
i_key_pad = [0x36 * blocksize] ⊕ key // Where ⊕ is exclusive or (XOR)
return hash(o_key_pad ∥ hash(i_key_pad ∥ message)) // Where ∥ is concatenation
end function
这是我写的代码(显然这给了我不合适的结果,我检查了给定的解决方案)。 块大小为 512 位。
我想我已经确定了我的代码失败的一个关键原因,我没有实现密钥的填充逻辑,因为我被要求放置前导零而不是像原来那样放置尾随零算法.
而且我真的不知道使用前导零填充是否会对数学有任何影响,或者如何使用它
其次,我不确定我是否正确地进行了字节运算。
这是我的代码:
private static string HMAC(string message)
{
//Every charecter corresponds to 4bits.
long hex_key = 0x0a7cb27e52;
//padding for an 64 Bit Key. 2 Chars = 1 Byte. Leading zeros I need (512-(10*4))/4 = 118
string asc_key = "0a7cb27e52";
//Did Not KnowWhere To Use
asc_key = asc_key.PadLeft(128, '0');
byte[] keyInBytes = Encoding.UTF8.GetBytes(asc_key);
var hexString = BitConverter.ToString(keyInBytes);
hexString = hexString.Replace("-", "");
//Wikipedia Style naming
long o_key_pad = (0x5c * 0x40) ^ hex_key;
long i_key_pad = (0x36 * 0x40) ^ hex_key;
return GetMD5Hash(o_key_pad.ToString() + GetMD5Hash(i_key_pad.ToString() + message));
}
public static String GetMD5Hash(String TextToHash)
{
//Check wether data was passed
if ((TextToHash == null) || (TextToHash.Length == 0))
{
return String.Empty;
}
//Calculate MD5 hash. This requires that the string is splitted into a byte[].
MD5 md5 = new MD5CryptoServiceProvider();
byte[] textToHash = Encoding.Default.GetBytes(TextToHash);
byte[] result = md5.ComputeHash(textToHash);
//Convert result back to string.
return System.BitConverter.ToString(result);
}
我哪里做错了?
I am not implementing the padding logic for the key, because I am
asked to put leading zeros and not trailing zeroes like the original
algorithm.
And I don't really know if using leading zeroes padding will make any
difference for the mathematics, or how to use it
它不会改变数学中的任何内容,但结果会有所不同。
Secondly, I am not sure if I am doing the byte math correctly.
你做的不对。您的代码有很多问题:
密钥可以有任何长度,并且密钥长度超过 64 位是很常见的,这将超过 long
.
的大小
o_key_pad
和i_key_pad
不重复填满块大小
HMAC
和 GetMD5Hash
获取并传送 string
数据。密码操作应该在二进制数据上执行,而不是在字符串上执行。
代码:
private static int BlockSize = 64;
public static byte[] HMAC(byte[] message)
{
byte[] key = {0x0a, 0x7c, 0xb2, 0x7e, 0x52};
if (key.Length > BlockSize) {
key = GetMD5Hash(key);
}
byte[] paddedKey = new byte[BlockSize];
key.CopyTo(paddedKey, BlockSize-key.Length);
byte[] o_key_pad = new byte[BlockSize];
byte[] i_key_pad = new byte[BlockSize];
for(int i = 0; i < BlockSize; i++) {
o_key_pad[i] = (byte)(0x5c ^ paddedKey[i]);
i_key_pad[i] = (byte)(0x36 ^ paddedKey[i]);
}
byte[] inner_hash = GetMD5Hash(concat(i_key_pad, message));
return GetMD5Hash(concat(o_key_pad, inner_hash));
}
private static byte[] concat(byte[] a1, byte[] a2) {
byte[] res = new byte[a1.Length + a2.Length];
a1.CopyTo(res, 0);
a2.CopyTo(res, a1.Length);
return res;
}
private static byte[] GetMD5Hash(byte[] ToHash)
{
MD5 md5 = new MD5CryptoServiceProvider();
return md5.ComputeHash(ToHash);
}
您可以围绕 HMAC
编写一个包装器来接收和传送 string
。
所以我正在尝试实现 HMAC function for academic purposes. Here is the algorithm as provided by Wikipedia:
的小型修改版本function hmac (key, message)
if (length(key) > blocksize) then
key = hash(key) // keys longer than blocksize are shortened
end if
if (length(key) < blocksize) then
// keys shorter than blocksize are zero-padded (where ∥ is concatenation)
key = key ∥ [0x00 * (blocksize - length(key))] // Where * is repetition.
end if
o_key_pad = [0x5c * blocksize] ⊕ key // Where blocksize is that of the underlying hash function
i_key_pad = [0x36 * blocksize] ⊕ key // Where ⊕ is exclusive or (XOR)
return hash(o_key_pad ∥ hash(i_key_pad ∥ message)) // Where ∥ is concatenation
end function
这是我写的代码(显然这给了我不合适的结果,我检查了给定的解决方案)。 块大小为 512 位。
我想我已经确定了我的代码失败的一个关键原因,我没有实现密钥的填充逻辑,因为我被要求放置前导零而不是像原来那样放置尾随零算法.
而且我真的不知道使用前导零填充是否会对数学有任何影响,或者如何使用它
其次,我不确定我是否正确地进行了字节运算。
这是我的代码:
private static string HMAC(string message)
{
//Every charecter corresponds to 4bits.
long hex_key = 0x0a7cb27e52;
//padding for an 64 Bit Key. 2 Chars = 1 Byte. Leading zeros I need (512-(10*4))/4 = 118
string asc_key = "0a7cb27e52";
//Did Not KnowWhere To Use
asc_key = asc_key.PadLeft(128, '0');
byte[] keyInBytes = Encoding.UTF8.GetBytes(asc_key);
var hexString = BitConverter.ToString(keyInBytes);
hexString = hexString.Replace("-", "");
//Wikipedia Style naming
long o_key_pad = (0x5c * 0x40) ^ hex_key;
long i_key_pad = (0x36 * 0x40) ^ hex_key;
return GetMD5Hash(o_key_pad.ToString() + GetMD5Hash(i_key_pad.ToString() + message));
}
public static String GetMD5Hash(String TextToHash)
{
//Check wether data was passed
if ((TextToHash == null) || (TextToHash.Length == 0))
{
return String.Empty;
}
//Calculate MD5 hash. This requires that the string is splitted into a byte[].
MD5 md5 = new MD5CryptoServiceProvider();
byte[] textToHash = Encoding.Default.GetBytes(TextToHash);
byte[] result = md5.ComputeHash(textToHash);
//Convert result back to string.
return System.BitConverter.ToString(result);
}
我哪里做错了?
I am not implementing the padding logic for the key, because I am asked to put leading zeros and not trailing zeroes like the original algorithm.
And I don't really know if using leading zeroes padding will make any difference for the mathematics, or how to use it
它不会改变数学中的任何内容,但结果会有所不同。
Secondly, I am not sure if I am doing the byte math correctly.
你做的不对。您的代码有很多问题:
密钥可以有任何长度,并且密钥长度超过 64 位是很常见的,这将超过
long
. 的大小
o_key_pad
和i_key_pad
不重复填满块大小HMAC
和GetMD5Hash
获取并传送string
数据。密码操作应该在二进制数据上执行,而不是在字符串上执行。
代码:
private static int BlockSize = 64;
public static byte[] HMAC(byte[] message)
{
byte[] key = {0x0a, 0x7c, 0xb2, 0x7e, 0x52};
if (key.Length > BlockSize) {
key = GetMD5Hash(key);
}
byte[] paddedKey = new byte[BlockSize];
key.CopyTo(paddedKey, BlockSize-key.Length);
byte[] o_key_pad = new byte[BlockSize];
byte[] i_key_pad = new byte[BlockSize];
for(int i = 0; i < BlockSize; i++) {
o_key_pad[i] = (byte)(0x5c ^ paddedKey[i]);
i_key_pad[i] = (byte)(0x36 ^ paddedKey[i]);
}
byte[] inner_hash = GetMD5Hash(concat(i_key_pad, message));
return GetMD5Hash(concat(o_key_pad, inner_hash));
}
private static byte[] concat(byte[] a1, byte[] a2) {
byte[] res = new byte[a1.Length + a2.Length];
a1.CopyTo(res, 0);
a2.CopyTo(res, a1.Length);
return res;
}
private static byte[] GetMD5Hash(byte[] ToHash)
{
MD5 md5 = new MD5CryptoServiceProvider();
return md5.ComputeHash(ToHash);
}
您可以围绕 HMAC
编写一个包装器来接收和传送 string
。