📄 libapr.c
字号:
#include <stdlib.h>
#include <string.h>
#include "libapr.h"
#include "md5.h"
static const char *apr1_id = "$apr1$";
static const char itoa64[] = /* 0 ... 63 => ASCII - 64 */
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static void to64(char *s, unsigned long v, int n)
{
while (--n >= 0) {
*s++ = itoa64[v&0x3f];
v >>= 6;
}
}
char *getRandomString(int Len, char *buf, const char *KeyStr)
{
static int Rand_Init = 0;
int MaxLen;
const char *key = itoa64;
char *p = buf;
if(KeyStr)
key = KeyStr;
MaxLen = strlen(key);
if(!Rand_Init)
{
#include <time.h>
time_t tm;
srand(time(&tm));
Rand_Init = 1;
}
if(p)
{
while(Len > 0)
{
*p++ = key[rand() % MaxLen];
Len--;
}
*p = '\0';
}
return buf;
}
int password_encode(const char *pw, const char *salt, char *result, size_t len)
{
char rand_salt[9];
char passwd[128] = "";
unsigned char Final[16];
const char *sp;
int sl;
md5_ctx_t cry1, cry2;
int pl, i;
if((salt == NULL) || ((salt != NULL) && (strlen(salt) == 0)))
{
int len;
getRandomString(0, NULL, NULL);
len = rand() & 0x03;
len += 3;
getRandomString(len, rand_salt, NULL);
sp = rand_salt;
sl = strlen(sp);
}
else
{
const char *ep;
sp = salt;
if (!strncmp(sp, apr1_id, strlen(apr1_id))) {
sp += strlen(apr1_id);
}
for (ep = sp; (*ep != '\0') && (*ep != '$') && (ep < (sp + 8)); ep++);
sl = ep - sp;
}
md5_init(&cry1);
md5_init(&cry2);
// md5(pw, apr1_id, salt)
md5_update(&cry1, pw, strlen(pw));
md5_update(&cry1, apr1_id, 6);
md5_update(&cry1, sp, sl);
// md5(pw, salt, pw)
md5_update(&cry2, pw, strlen(pw));
md5_update(&cry2, sp, sl);
md5_update(&cry2, pw, strlen(pw));
md5_final(&cry2, Final);
for(pl = strlen(pw); pl > 0; pl -= 16)
md5_update(&cry1, Final, pl > 16 ? 16 : pl);
memset(Final, 0, 16);
for(i = strlen(pw); i != 0; i >>= 1)
{
if (i & 1)
md5_update(&cry1, Final, 1);
else
md5_update(&cry1, pw, 1);
}
/*
* Now make the output string. We know our limitations, so we
* can use the string routines without bounds checking.
*/
strcpy(passwd, apr1_id);
strncat(passwd, sp, sl);
strcat(passwd, "$");
md5_final(&cry1, Final);
for (i = 0; i < 1000; i++)
{
md5_ctx_t cry3;
md5_init(&cry3);
/*
* apr_md5_final clears out ctx1.xlate at the end of each loop,
* so need to to set it each time through
*/
if (i & 1)
md5_update(&cry3, pw, strlen(pw));
else
md5_update(&cry3, Final, 16);
if (i % 3)
md5_update(&cry3, sp, sl);
if (i % 7)
md5_update(&cry3, pw, strlen(pw));
if (i & 1)
md5_update(&cry3, Final, 16);
else
md5_update(&cry3, pw, strlen(pw));
md5_final(&cry3, Final);
}
{
char *p = passwd + strlen(passwd);
unsigned long l;
l = (Final[ 0]<<16) | (Final[ 6]<<8) | Final[12]; to64(p, l, 4); p += 4;
l = (Final[ 1]<<16) | (Final[ 7]<<8) | Final[13]; to64(p, l, 4); p += 4;
l = (Final[ 2]<<16) | (Final[ 8]<<8) | Final[14]; to64(p, l, 4); p += 4;
l = (Final[ 3]<<16) | (Final[ 9]<<8) | Final[15]; to64(p, l, 4); p += 4;
l = (Final[ 4]<<16) | (Final[10]<<8) | Final[ 5]; to64(p, l, 4); p += 4;
l = Final[11] ; to64(p, l, 2); p += 2;
*p = '\0';
}
memcpy(result, passwd, len);
return 0;
}
int password_validate(const char *passwd, const char *hash)
{
char key[128];
password_encode(passwd, hash, key, 128);
if(strlen(key) == strlen(hash))
if(strcmp(key, hash) == 0)
return 1;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -