HMAC-MD5实现

实现MD5算法,和HMAC算法,Visual Studio 2019  x86编译。

MD5算法实现

unsigned int F(unsigned int X, unsigned int Y, unsigned int Z) {
	return (X & Y) | ((~X) & Z);
}

unsigned int G(unsigned int X, unsigned int Y, unsigned int Z) {
	return (X & Z) | (Y & (~Z));
}

unsigned int H(unsigned int X, unsigned int Y, unsigned int Z) {
	return X ^ Y ^ Z;
}

unsigned int I(unsigned int X, unsigned int Y, unsigned int Z) {
	return Y ^ (X | (~Z));
}

unsigned int FF(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned long long Mj, unsigned int s, unsigned int ti) {
	return  (unsigned int)(b + rol(a + F(b, c, d) + Mj + ti, s));
}

unsigned int GG(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned long long Mj, unsigned int s, unsigned int ti) {
	return (unsigned int)(b + rol(a + G(b, c, d) + Mj + ti, s));
}

unsigned int HH(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned long long Mj, unsigned int s, unsigned int ti) {
	return (unsigned int)(b + rol(a + H(b, c, d) + Mj + ti, s));
}

unsigned int II(unsigned int a, unsigned int b, unsigned int c, unsigned int d, unsigned long long Mj, unsigned int s, unsigned int ti) {
	return (unsigned int)(b + rol(a + I(b, c, d) + Mj + ti, s));
}

unsigned int getInt(char* message, int offset) {
	unsigned int* pi = (unsigned int*) (&message[offset]);
	return (unsigned int)*pi;
}

void init() {
	for (int i = 1; i <= 64; i++)
		T[i - 1] = (unsigned int)(MAX * __abs(sin(i)));
}

unsigned int* MD5(char* message, size_t mLen) {
	init();
	size_t padLen = 56 - mLen % 64;
	unsigned long long bitLen = mLen * 8;

	if (padLen > 0) {
		message = memconcat(message, mLen, "\x80", 1);
		mLen += 1;

		if (padLen - 1 > 0) {
			char* o = (char*)malloc(padLen - 1);
			memset(o, 0, padLen - 1);
			message = memconcat(message, mLen, o, padLen -1);
			mLen += padLen - 1;
		}
	}

	message = memconcat(message, mLen, (char*)&bitLen, 8);
	mLen += 8;

	unsigned int A = 0x67452301;
	unsigned int B = 0xEFCDAB89;
	unsigned int C = 0x98BADCFE;
	unsigned int D = 0x10325476;


	for (size_t group = 0; group < mLen / 64; group++) {

		unsigned int a = A, b = B, c = C, d = D;
		unsigned int offset = group * 64;

		for (int i = 0; i < 4; i++) {
			int p1 = i * 4;
			int p2 = i * 4;
			a = FF(a, b, c, d, getInt(message, offset + M[0][p1 + 0] * 4), Matrix[0][0], T[p2 + 0]);
			d = FF(d, a, b, c, getInt(message, offset + M[0][p1 + 1] * 4), Matrix[0][1], T[p2 + 1]);
			c = FF(c, d, a, b, getInt(message, offset + M[0][p1 + 2] * 4), Matrix[0][2], T[p2 + 2]);
			b = FF(b, c, d, a, getInt(message, offset + M[0][p1 + 3] * 4), Matrix[0][3], T[p2 + 3]);
		}

		for (int i = 0; i < 4; i++) {
			int p1 = i * 4;
			int p2 = 16 + i * 4;
			a = GG(a, b, c, d, getInt(message, offset + M[1][p1 + 0] * 4), Matrix[1][0], T[p2 + 0]);
			d = GG(d, a, b, c, getInt(message, offset + M[1][p1 + 1] * 4), Matrix[1][1], T[p2 + 1]);
			c = GG(c, d, a, b, getInt(message, offset + M[1][p1 + 2] * 4), Matrix[1][2], T[p2 + 2]);
			b = GG(b, c, d, a, getInt(message, offset + M[1][p1 + 3] * 4), Matrix[1][3], T[p2 + 3]);
		}

		for (int i = 0; i < 4; i++) {
			int p1 = i * 4;
			int p2 = 32 + i * 4;
			a = HH(a, b, c, d, getInt(message, offset + M[2][p1 + 0] * 4), Matrix[2][0], T[p2 + 0]);
			d = HH(d, a, b, c, getInt(message, offset + M[2][p1 + 1] * 4), Matrix[2][1], T[p2 + 1]);
			c = HH(c, d, a, b, getInt(message, offset + M[2][p1 + 2] * 4), Matrix[2][2], T[p2 + 2]);
			b = HH(b, c, d, a, getInt(message, offset + M[2][p1 + 3] * 4), Matrix[2][3], T[p2 + 3]);
		}

		for (int i = 0; i < 4; i++)  {
			int p1 = i * 4;
			int p2 = 48 + i * 4;
			a = II(a, b, c, d, getInt(message, offset + M[3][p1 + 0] * 4), Matrix[3][0], T[p2 + 0]);
			d = II(d, a, b, c, getInt(message, offset + M[3][p1 + 1] * 4), Matrix[3][1], T[p2 + 1]);
			c = II(c, d, a, b, getInt(message, offset + M[3][p1 + 2] * 4), Matrix[3][2], T[p2 + 2]);
			b = II(b, c, d, a, getInt(message, offset + M[3][p1 + 3] * 4), Matrix[3][3], T[p2 + 3]);
		}

		A = a + A;
		B = b + B;
		C = c + C;
		D = d + D;
	}

	unsigned int* r = (unsigned int*)malloc(sizeof(int) * 4);
	if (r != NULL) {
		r[0] = A; 
		r[1] = B; 
		r[2] = C; 
		r[3] = D; 
	}
	return r;
}

HMAC实现

unsigned int* HMAC_MD5(char* key, char* message) {
    size_t keyLen = strlen(key);
    size_t msgLen = strlen(message);

    if (keyLen > MD5_BLOCK_SIZE) {
        key = MD5(key, keyLen);
        keyLen = MD5_DIGEST_SIZE;
    }

    if (keyLen < MD5_BLOCK_SIZE) {
        int padLen = MD5_BLOCK_SIZE - keyLen;
        char* pad = malloc(padLen);
        if (pad != NULL) {
            memset(pad, 0, padLen);
            key = memconcat(key, keyLen, pad, padLen);
            keyLen = keyLen + padLen; // must =BLOCKSIZE
        }
    }

    unsigned char* iKey = malloc(keyLen);
    unsigned char* oKey = malloc(keyLen);

    for (unsigned int i = 0; i < keyLen; i++) {
        iKey[i] = key[i] ^ IPAD;
        oKey[i] = key[i] ^ OPAD;
    }

    unsigned char* text = memconcat(iKey, keyLen, message, msgLen);
    unsigned int* m = MD5(text, keyLen + msgLen);
    text = memconcat(oKey, keyLen, m, 16);

    m = MD5(text, keyLen + 16);
    return m;
}

执行:

int main()
{
    unsigned int* r1 = MD5("Hello World", strlen("Hello world"));
    for (int i = 0; i < 4; i++) {
        printf("%X ", b2l(r1[i]));
    }
    printf("\n");


    unsigned int* r = HMAC_MD5("key", "Hello World");
    for (int i = 0; i < 4; i++) {
        printf("%X ", b2l(r[i]));
    }

    return 0;
}

显示结果如下:

HMAC-MD5实现_第1张图片

你可能感兴趣的:(程序设计,算法,密码学)