在Vala中编写Hmac函数
问题描述:
我正在为Vala和Linux写一个跨平台的应用程序。我需要实现Hmac的安全性;但不幸的是,GHmac类(link)尚未被移植到Windows。我在wikipedia上找到了Hmac的算法(link),我相信我正确实现了它,但是与内置类相比,我没有得到相同的结果。如果任何人都可以帮我找到一个令人惊叹的bug,那么下面是我的功能。在Vala中编写Hmac函数
public static string compute_for_data(ChecksumType type, uint8[] key,
uint8[] data) {
int block_size = 64;
uint8[] mod_key = key;
uint8[] outer = new uint8[block_size];
uint8[] inner = new uint8[block_size];
if (mod_key.length > block_size) {
mod_key = Checksum.compute_for_data(type, key).data;
}
mod_key.resize(block_size);
for (int i=0; i < mod_key.length; i++) {
outer[i] = mod_key[i]^0x5c;
inner[i] = mod_key[i]^0x36;
}
int i = inner.length;
inner.resize(i + data.length);
for (int j=0; j < data.length; j++) {
inner[i + j] = data[j];
}
inner = Checksum.compute_for_data(type, inner).data;
i = outer.length;
outer.resize(i + inner.length);
for (int j=0; j < inner.length; j++) {
outer[i + j] = inner[j];
}
return Checksum.compute_for_data(type, outer);
}
答
我知道它的俗气回答自己的问题,但我设法在朋友的帮助下解决它,所以这里是解决方案。基本上,当我使用Checksum.compute_for_data函数时,它返回一个不是十六进制数据的十六进制字符串,并打破了算法。这是更正后的版本:
public static string compute_for_data(ChecksumType type, uint8[] key,
uint8[] data) {
int block_size = 64;
switch (type) {
case ChecksumType.MD5:
case ChecksumType.SHA1:
block_size = 64; /* RFC 2104 */
break;
case ChecksumType.SHA256:
block_size = 64; /* RFC draft-kelly-ipsec-ciph-sha2-01 */
break;
}
uint8[] buffer = key;
if (key.length > block_size) {
buffer = Checksum.compute_for_data(type, key).data;
}
buffer.resize(block_size);
Checksum inner = new Checksum(type);
Checksum outer = new Checksum(type);
uint8[] padding = new uint8[block_size];
for (int i=0; i < block_size; i++) {
padding[i] = 0x36^buffer[i];
}
inner.update(padding, padding.length);
for (int i=0; i < block_size; i++) {
padding[i] = 0x5c^buffer[i];
}
outer.update(padding, padding.length);
size_t length = buffer.length;
inner.update(data, data.length);
inner.get_digest(buffer, ref length);
outer.update(buffer, length);
return outer.get_string();
}