使用 openssl 在 iPhone 上正确获取 HMACSHA1
哎呀,我的头好痛!
上下文
我需要编写一些 C/Objective-C 代码来解密存储在远程服务器上的文件。加密是开源的,并用 C# 编写,
我使用的是该项目中的 libssl.a 和 libcrypto.a;
https://github.com/x2on/OpenSSL-for-iPhone
我的第一个障碍是甚至使字符串的 HMACSHA1 正确:( 根据此处的参考站点,SHA1 似乎是正确的 - http://hash.online-convert.com/sha1-generator 但 HMAC 不是。好的,现在一些代码;
NSString *input = @"wombats";
// Define some strings etc that we need
unsigned char *inStrg = malloc(256);
inStrg = (unsigned char *)[input UTF8String];
unsigned long lngth = [input length];
unsigned char result [EVP_MAX_MD_SIZE];
unsigned char hmacresult [EVP_MAX_MD_SIZE];
unsigned char newPassPhrase[25];
memset(newPassPhrase, 0, 25);
unsigned char salt[] = "\x01\x02\x03\x04\x05\x06\x07\x08";
// The real code requires us to re-hash the input 1000 times. For now lets
// just check it with 10 (hey even the first is wrong).
for (int i=0; i<10; i++)
{
// Use openssl
SHA_CTX shaContext;
SHA1_Init(&shaContext);
SHA1_Update(&shaContext, inStrg, lngth );
SHA1_Final(result, &shaContext);
unsigned int len;
// If I look at result now, it matches the reference, so I think it is the next stage that goes wrong.
HMAC(EVP_sha1(),salt,8,result,20,hmacresult,&len);
printf("HMAC ----------------- : ");
hexPrint(hmacresult,len);
// Copy the result to the input so we can re-hash;
lngth = len;
memcpy((char *)inStrg,(char *)hmacresult,len);
}
我尝试匹配的代码是以下 C# 片段。此代码生成正确的输出是来自生产服务器的摘录
byte[] salt={0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
UTF8Encoding utf8 = new UTF8Encoding();
byte[] data = utf8.GetBytes("wombats");
HMACSHA1 sha1= new HMACSHA1();
sha1.Key = salt;
for(int i=0; i<10; i++)
{
sha1.ComputeHash(data);
data = sha1.Hash;
Console.WriteLine(System.BitConverter.ToString(data));
}
如果我编译并运行 C# 代码,我得到的输出是以下序列
DC-F3-1C-C1-2F-8A-86-16-CC-74-1E-DA-25-7B-FF-16-6E-EB-2A-0F
E7-6A-F4-C6-73-07-DB-E8-52-82-9E-D1-96-BF-06-95-85-C6-94-F4
1F-E2-61-BC-F0-08-92-3C-14-70-2B-89-EB-46-C9-20-A5-90-65-9B
etc
如果我查看 iPhone 版本的输出,我得到以下结果
44-35-5b-bb-41-0e-bc-c3-d3-58-62-e6-5c-a0-51-6b-bc-97-11-f6
4c-3b-61-bd-1f-f7-72-13-af-1b-5e-5e-e3-70-8a-31-08-11-67-f2
41-56-8d-41-c1-3e-02-d0-d2-76-ad-d3-49-ba-71-ff-34-d7-3e-8b
etc
: 我
如果我只检查 SHA1 部分,这似乎是正确的,所以我猜测要么我使用了错误的参数 HMAC,要么 C# HMACSHA1 做了一些与我的预期不同的事情,
应该添加这一点 。使用合适的 ASCII 盐,这是在线生成器的结果 http://hash.online-convert。 com/sha1-generator 也与 C# 代码匹配,这让我强烈怀疑 iPhone 上的 C 代码是错误的。
谁能帮我解决问题是什么,我现在没有想法了!
Argh, my head hurts!
Context
I need to write some C/Objective-C code to decrypt files that are stored on a remote server. The encryption is open-source and written in C#
I'm using libssl.a and libcrypto.a from this project;
https://github.com/x2on/OpenSSL-for-iPhone
My first hurdle is even getting the HMACSHA1 of a string to be correct :( The SHA1 seems to be correct according to a reference site here - http://hash.online-convert.com/sha1-generator but the HMAC is not. OK, so now some code;
NSString *input = @"wombats";
// Define some strings etc that we need
unsigned char *inStrg = malloc(256);
inStrg = (unsigned char *)[input UTF8String];
unsigned long lngth = [input length];
unsigned char result [EVP_MAX_MD_SIZE];
unsigned char hmacresult [EVP_MAX_MD_SIZE];
unsigned char newPassPhrase[25];
memset(newPassPhrase, 0, 25);
unsigned char salt[] = "\x01\x02\x03\x04\x05\x06\x07\x08";
// The real code requires us to re-hash the input 1000 times. For now lets
// just check it with 10 (hey even the first is wrong).
for (int i=0; i<10; i++)
{
// Use openssl
SHA_CTX shaContext;
SHA1_Init(&shaContext);
SHA1_Update(&shaContext, inStrg, lngth );
SHA1_Final(result, &shaContext);
unsigned int len;
// If I look at result now, it matches the reference, so I think it is the next stage that goes wrong.
HMAC(EVP_sha1(),salt,8,result,20,hmacresult,&len);
printf("HMAC ----------------- : ");
hexPrint(hmacresult,len);
// Copy the result to the input so we can re-hash;
lngth = len;
memcpy((char *)inStrg,(char *)hmacresult,len);
}
The code I am trying to match is the following C# fragment. This code generates the correct output and is an extract from the production server.
byte[] salt={0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
UTF8Encoding utf8 = new UTF8Encoding();
byte[] data = utf8.GetBytes("wombats");
HMACSHA1 sha1= new HMACSHA1();
sha1.Key = salt;
for(int i=0; i<10; i++)
{
sha1.ComputeHash(data);
data = sha1.Hash;
Console.WriteLine(System.BitConverter.ToString(data));
}
If I compile and run the C# code, the output I get is the following sequence;
DC-F3-1C-C1-2F-8A-86-16-CC-74-1E-DA-25-7B-FF-16-6E-EB-2A-0F
E7-6A-F4-C6-73-07-DB-E8-52-82-9E-D1-96-BF-06-95-85-C6-94-F4
1F-E2-61-BC-F0-08-92-3C-14-70-2B-89-EB-46-C9-20-A5-90-65-9B
etc
If I look at the output from the iPhone version, I get the following;
44-35-5b-bb-41-0e-bc-c3-d3-58-62-e6-5c-a0-51-6b-bc-97-11-f6
4c-3b-61-bd-1f-f7-72-13-af-1b-5e-5e-e3-70-8a-31-08-11-67-f2
41-56-8d-41-c1-3e-02-d0-d2-76-ad-d3-49-ba-71-ff-34-d7-3e-8b
etc
So there is clearly something seriously wrong.
If I check just the SHA1 part, that seems correct, so I'm guessing that either I'm using HMAC with the wrong parameters, or the C# HMACSHA1 does something different to my expectations.
I should add that if I use a suitable ASCII salt, the result of the online generator here http://hash.online-convert.com/sha1-generator also matches the C# code which strongly leads me to suspect it is my C on the iPhone that is wrong.
Can anyone assist me with working out what the problem is, I'm running out of ideas at the moment!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
删除重复的 SHA1 即可修复该问题。卫生部!
把这一切都删掉。
Removing the duplicate SHA1 fixes it. DOH!
Delete all of this.
仅使用
中的方法(不是框架,只是/usr/include
中的标头)可能值得您花时间。It could be worth your time to just use the methods in
<CommonCrypto/CommonHMAC.h>
(not a framework, just headers in/usr/include
).