|
Tried to use HMAC and the digest fucntion not returning correctly.
I am using VC6.Below is the response for Digest in debug mode.
digest 0x0012f228 "¶1†Urdâ‹À¶û7ŒŽñF¾"
code is as below :
char cstr1[30]="Hi There";
const char * test = ( const char *) cstr1;
unsigned char *test1 = ( unsigned char *) cstr1;
memset(Key, 0x0b, 20) ;
CHMAC_SHA1 HMAC_SHA1 ;
HMAC_SHA1.HMAC_SHA1(test1, strlen(test), Key, sizeof(Key), digest) ;
|
|
|
|
|
Hi, thanks for your sharing.
I hava countered a problem, the result of HMAC-SHA is the same even the string and/or key change a little.
I hava set multi-byte charater set in vs 2010;
Is this matters?
Thanks
|
|
|
|
|
thanks for your src.I run it on my computer.no "string to hex" method! could you provide
|
|
|
|
|
|
The code in method HMAC_SHA1 is copying the ipad and the input text into a buffer of fixed size, without checking the length of the input. This will segfault and crash with input text larger than 4076 bytes (I am trying to sign files and executable which are larger than the buffer size).
The buffer copy is also not necessary as you can as well call CSHA1::Update several times with each chunk of data, first with the ipad and then with the text.
CSHA1::Update( (UINT_8 *) m_ipad, sizeof( m_ipad ) );
CSHA1::Update( (UINT_8 *) text, text_len );
You can do the same with the opad buffer.
CSHA1::Update( (UINT_8 *) m_opad, sizeof( m_opad ) );
CSHA1::Update( (UINT_8 *) szReport, SHA1_DIGEST_LENGTH );
Now you can completely remove AppendBuf1 and AppendBuf2, as they are not used anymore. I tested the change and it produces the same result on my (smaller) files and on the test example "Hi There".
Btw: a different layout like the one used in CSHA1 would be nice, where I can call a method several times with chunks of data from a file and finally call a function to get the hash code. With the current implementation I need to load the whole file into a flat array first.
I also modified HMAC_SHA1, Update and Transform to take 'const' arguments whenever applicable. That way you can use 'char' or 'const char' as arguments for key and text without any compiler errors.
Additionally, although it is common in optimized algorithms to use unions like SHA1_WORKSPACE_BLOCK, the resulting behavior (e.g. after writing uint32 and then reading uint8) is unspecified in any C++ compiler and should therefor be avoided. It is unspecified how those two arrays are exactly padded and aligned in memory and it violates strict aliasing causing the optimizer to do unintended things. Endianness seems to be taken care of explicitly, but would also be a huge problem in general.
|
|
|
|
|
Here is my source code in C#.
string apiKey = "1234";
string payload = "4321";
byte[] bKey = Encoding.Default.GetBytes(apiKey);
byte[] bPayload = Encoding.Default.GetBytes(payload);
HMACSHA1 hmacSha = new HMACSHA1(bKey, true);
hmacSha.Initialize();
byte[] bytes = hmacSha.ComputeHash(bPayload);
string signature = BitConverter.ToString(bytes).Replace("-", string.Empty);
Console.WriteLine(signature);
# I get 10BF095402AAC48CE0BF410BCBFF730F1CE52887 where with your code I get 10DF6D7068F4320F86ECE0002D52A071042CB4F5, this is how I use it, thanks, sorry for my pool English.
BYTE Key[20] ;
BYTE digest[20] ;
BYTE input[20];
printf("%d",sizeof(Key));
memset(Key, 0, 20);
memset(input,0,20);
int count = 0;
char *test = "4321";
for (char *s = test; strlen(s)>0; s+=2)
{
if(*s>='0' && *s<='9')
input[count]=*s-'0';
else if(*s>='a'&& *s<='f')
input[count]=*s-'a'+10;
if(strlen(s)>1)
{
input[count]*=16;
if(*(s+1)>='0' && *(s+1)<='9') input[count]+=(*(s+1)-'0');
if(*(s+1)>='a'&& *(s+1)<='f') input[count]+=(*(s+1)-'a'+10);
}
count++;
}
count = 0;
char * strkey = "1234";
for (char *s1 = strkey; strlen(s1)>0; s1+=2)
{
if(*s1>='0' && *s1<='9')
Key[count]=*s1-'0';
else if(*s1>='a'&& *s1<='f')
Key[count]=*s1-'a'+10;
if(strlen(s1)>1)
{
Key[count]*=16;
if(*(s1+1)>='0' && *(s1+1)<='9') Key[count]+=(*(s1+1)-'0');
if(*(s1+1)>='a'&& *(s1+1)<='f') Key[count]+=(*(s1+1)-'a'+10);
}
count++;
}
CHMAC_SHA1 HMAC_SHA1 ;
HMAC_SHA1.HMAC_SHA1(input, 2, Key, 2, digest) ;
char temp[41];
memset(temp,0,41);
int i = 0;
for (i = 0; i<20;i++)
{
sprintf(temp+i*2,"%02X",digest[i]);
}
printf ("%s",temp);
|
|
|
|
|
Do you try to use "Hi There" string and check if the digest is the same as
"0xb617318655057264e28bc0b6fb378c8ef146be00" ???
|
|
|
|
|
the code is :
#include <fstream>
#include <string>
#include "HMAC_SHA1.h"
using namespace std;
int main()
{
fstream fout("D:\\t1.txt",ios::out);
fout << "begin" <<endl;
//CHMAC_SHA1 HMAC_SHA1;
BYTE Key[20] ;
BYTE digest[20] ;
const char *test = "Hi There" ;
memset(Key, 0x0b,20) ;
CHMAC_SHA1 HMAC_SHA1 ;
HMAC_SHA1.HMAC_SHA1((BYTE*)test, strlen(test), Key, sizeof(Key), digest) ;
fout<<(char*)digest<<endl;
fout<<"Hello world"<<endl;
fout.close();
return 0;
}
the result is :
begin
?1哢rd鈰蓝?寧馞?
Hello world
so I want to know why the reslut is wrong? your code ?or my code if my code is wrong,please tell my the reason and how to correct it ?
|
|
|
|
|
You are sending a Binary data in ASCII mode.
The binary Digest data is converted to text.
You have to set the fout as a binary mode.
|
|
|
|
|
Iam using folwing code
but
end up with many errors with conversions
please help me
int main()
{
cout << "begin" ;
//CHMAC_SHA1 HMAC_SHA1;
BYTE Key[20] ;
BYTE digest[20] ;
unsigned char *test = "Hi There" ;
//int unsigned char*y = (char) *test;
//y = (char)test;
//memset(Key, 0x0b,20) ;
CHMAC_SHA1 HMAC_SHA1 ;
HMAC_SHA1.HMAC_SHA1(test, strlen(test), Key, sizeof(Key), digest) ;
}
|
|
|
|
|
Hi there,
I was trying to run the C++ implemention of HMAC-SHA. I have done the neccesary linkage of the the external library ( using Crypto++. ).
I added the following test code to the end of HMAC.cpp file:
int main()
{
BYTE Key[20] ;
BYTE digest[20] ;
74: unsigned char *test = "Hi There" ;
memset(Key, 0x0b, 20 ) ;
CHMAC_SHA1 HMAC_SHA1 ;
77: HMAC_SHA1.HMAC_SHA1(test, strlen(test), Key, sizeof(Key), digest) ;
}
I am getting this error:
74: error:invalid conversion from 'const char*' to 'unsigned char*'
77: error:invalid conversion from 'unsigned char*' to 'const char*'
77: error:initializing argument 1 of size_t strlen(const char*)
if I comment out ( // ) the main function, i get the following errors:
/*STEP 1*/
line 26: CSHA1::Update ((UINT_8*)key, key_len);
26: error: undefined reference to 'CSHA1::Update(unsigned char*, unsigned long)'
Can I get some help?. I will be glad to hear from you.
Godwin
|
|
|
|
|
Hi
Have you add the CSHA files to your project ???
What kind of platform you are using for this proejct ???
You will get the errors because the compiler checks syntax for the pointer to a string as a const pointer.
And parameter 1 for CHMAC_SHA1 is a pointer to unsigned char.
Try to cast the "unsigned char * test" to "const char * test".
|
|
|
|
|
In the article:
memset(Key, 20, 0x0b) ;
I think it should be:
memset(Key, 0x0b, 20) ;
"Theory is when you know something, but it doesn't work.
Practice is when something works, but you don't know why.
Programmers combine theory and practice: Nothing works and they don't know why."
|
|
|
|
|
You are correct. It should be memset(Key, 0x0b, 20) ;
|
|
|
|
|
Thanks folks.
It's a typo, I will try to fix it.
|
|
|
|
|
Hi there,
Excellent, this is the sort of code example I have been looking for.
I also want to see example code for the receiver processing that occurs where the HMAC digest values are compared with one another and if the sending digest does not match the receiving digest then the packet is discarded etc. Is there any example open source code out there that also implements that functionality?
Many thanks,
|
|
|
|
|
There is a small bug in the HMAC_SHA1.cpp code when using long key's.
Key's must be hashed when the size is longer than the block size but the code checks the digest length instead.
This is the fix:
/* STEP 1 */
//if (key_len > SHA1_DIGEST_LENGTH)
if (key_len > SHA1_BLOCK_SIZE)
{
Thanks,
Bruno
modified on Thursday, March 6, 2008 10:05 AM
|
|
|
|
|
Thanks for the HMAC implementation, works fine on Mac OSX 10.5!
Bruno
|
|
|
|
|
hi Bruno1999,
Can u offer some advice here on how to use the HMAC implementation.
I tried using it by got some error messages which I posted for help.
I used the following test data:
int main()
{
BYTE Key[20] ;
BYTE digest[20] ;
char *test = "Hi There";
unsigned char* y;
y = (unsigned char) test;
memset(Key, 0x0b, 20 ) ;
CHMAC_SHA1 HMAC_SHA1 ;
HMAC_SHA1.HMAC_SHA1(y, sizeof(y), Key, sizeof(Key), digest) ;
cout << "Digest: " << digest << endl;
}
Error encountered on the following lines:
CSHA1::Update((UNIT_8 *)key, key_len);
CSHA1::Update((UNIT_8 *)AppendBuf1, sizeof(m_ipad) + text_len);
CSHA1::Update((UNIT_8 *)AppendBuf2, sizeof(m_opad) + SHA1_DIGEST_LENGTH);
Error: undefined reference to 'CSHA1::Update(unsigned char*, unsigned long)'
I will be grateful to hear from you.
Godwin.
|
|
|
|
|