研二
HMAC
RFC 2104
Hash((Key ^ opad) || Hash((K ^ ipad) || message))
哈希函数是我自己瞎写的,先对入参字符串进行填充(16字节),然后将每一组字符串与前一组进行异或。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>#define IN
#define OUT#define HASHFUNC mabowenhash
#define HASHBLOCKLEN 16int mabowenhash(unsigned char *indata, unsigned int indatalen, unsigned char *outdata, unsigned int *outdatalen) {
if (NULL == indata || NULL == outdata || 0 == indatalen || 0 == *outdatalen) {
printf("error: indata invalid.\n");return 1;}int ret;int i, j;int flag = indatalen % HASHBLOCKLEN ? indatalen / HASHBLOCKLEN + 1 : indatalen / HASHBLOCKLEN;/// log ///printf("flag:%d\n", flag);/// log ///int padlen;unsigned int templen;unsigned char *paddingindata = NULL;unsigned int paddingindatalen = indatalen;unsigned char temphash[HASHBLOCKLEN] = {
0 };unsigned char tempdata[HASHBLOCKLEN] = {
0 };paddingindata = (unsigned char *)malloc(indatalen + 16);//paddingif (indatalen % HASHBLOCKLEN) {
padlen = HASHBLOCKLEN - indatalen % HASHBLOCKLEN;memcpy(paddingindata, indata, indatalen);memset(paddingindata + indatalen, 0x00, padlen);paddingindatalen += padlen;}/// log ///printf("paddingindata:\n");for(i = 0; i < paddingindatalen; i++)printf("%02x ", *(paddingindata + i));printf("\nend\n");/// log ///for (i = 0; i < flag; i++) {
memcpy(tempdata, paddingindata + i * 16, HASHBLOCKLEN);/// log ///printf("tempdata:\n");for(j = 0; j < HASHBLOCKLEN; j++)printf("%02x ", tempdata[j]);printf("\nend\n");/// log ///for (j = 0; j < HASHBLOCKLEN; j++) {
temphash[j] ^= tempdata[j];}/// log ///printf("temphash:\n");for(j = 0; j < HASHBLOCKLEN; j++)printf("%02x ", temphash[j]);printf("\nend\n");/// log ///}memcpy(outdata, tempdata, HASHBLOCKLEN);*outdatalen = HASHBLOCKLEN;free(paddingindata);return 0;
}int HMAC(IN unsigned char *key, IN unsigned int keylen,IN unsigned char *message, IN unsigned int messagelen,OUT unsigned char *hmac, OUT unsigned int *hmaclen) {
int ret;int i;int keypaddinglen;unsigned char opad = 0x5A;unsigned char ipad = 0x36;unsigned int hash1len = HASHBLOCKLEN;unsigned int hash2len = HASHBLOCKLEN;unsigned char padkey[HASHBLOCKLEN];unsigned char *opadxorpadkey;unsigned char *ipadxorpadkey;unsigned char *hash1;unsigned char *hash2;opadxorpadkey = (unsigned char *)malloc(HASHBLOCKLEN * 2);ipadxorpadkey = (unsigned char *)malloc(HASHBLOCKLEN + messagelen);hash1 = (unsigned char *)malloc(HASHBLOCKLEN);hash2 = (unsigned char *)malloc(HASHBLOCKLEN);memcpy(padkey, key, keylen);//keypaddingif (keylen < HASHBLOCKLEN) {
keypaddinglen = HASHBLOCKLEN - keylen;memset(padkey + keylen, 0x00, keypaddinglen);}//ipad ^ keyfor (i = 0; i < HASHBLOCKLEN; i++) {
*(ipadxorpadkey + i) = *(padkey + i) ^ ipad;}/// log ///printf("ipadxorpadkey:\n");for(i = 0; i < HASHBLOCKLEN; i++)printf("%02x ", *(ipadxorpadkey + i));printf("\nend\n");/// log /////opad ^ keyfor (i = 0; i < HASHBLOCKLEN; i++) {
*(opadxorpadkey + i) = *(padkey + i) ^ opad;}/// log ///printf("opadxorpadkey:\n");for(i = 0; i < HASHBLOCKLEN; i++)printf("%02x ", *(opadxorpadkey + i));printf("\nend\n");/// log /////concatenate ipadxorpadkey with messagememcpy(ipadxorpadkey + HASHBLOCKLEN, message, messagelen);//hash concatenated ipadxorpadkey-messageret = HASHFUNC(ipadxorpadkey, HASHBLOCKLEN + messagelen, hash1, &hash1len);if (ret) {
printf("ret\n");return ret;}//concatenate opadxorpadkey with HashedIpadXorDatamemcpy(opadxorpadkey + HASHBLOCKLEN, hash1, hash1len);/// log ///printf("opadxorpadkey:\n");for(i = 0; i < hash1len; i++)printf("%02x ", *(opadxorpadkey + i));printf("\nend\n");/// log /////hash final dataret = HASHFUNC(opadxorpadkey, HASHBLOCKLEN * 2, hash2, &hash2len);if (ret) {
printf("ret\n");return ret;}/// log ///printf("hash2:\n");for(i = 0; i < hash2len; i++)printf("%02x ", hash2 + i);printf("\nend\n");/// log ///memcpy(hmac, hash2, HASHBLOCKLEN);*hmaclen = HASHBLOCKLEN;free(opadxorpadkey);free(ipadxorpadkey);free(hash1);free(hash2);return ret;
}int main() {
int ret;int i;unsigned char key[HASHBLOCKLEN] = "1234567812345678";unsigned int keylen = HASHBLOCKLEN;unsigned char *message = "mabowenidsahfudhsuiafhodshauifhdsoiahfiuosd";unsigned int messagelen = 43;unsigned char hmacdata[HASHBLOCKLEN] = {
0};unsigned int hmacdatalen = HASHBLOCKLEN;ret = HMAC(key, keylen, message, messagelen, hmacdata, &hmacdatalen);if (ret) {
printf("error\n");return ret;}printf("hmacdata\n");for (i = 0; i < hmacdatalen; i++) {
printf("%02x ", hmacdata[i]);}printf("\nend of hmacdata\n");return ret;
}
函数指针和指针函数
在看cJSON库的时候看到了指针函数的概念:
static void *(*cJSON_malloc)(size_t sz) = malloc;
static void (*cJSON_free)(void *ptr) = free;
以第一个函数作为例子,此处定义了cJSON_malloc的指针函数,其是一个指针。(*func)这种定义方法即定义了一个指向函数的变量,改变量的内容存的是一个函数的入口。任何一个函数在编译的时候都有一个入口值,在程序运行的过程中,如果需要某一函数,cpu便会寻找该函数段的入口值然后开始执行接下来内存段的命令。
static void * 为malloc函数的类型,指针函数必须保证变量和所指向的函数类型保持一致。
在指针函数变量定义之后就是其所指向的函数需要接收的变量值,变量值也应与所指向函数的变量类型和数量保持一致。