实现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;
}
显示结果如下: