好的,我花了最近几天研究这个,我不相信Apache本身支持的散列函数已经过时了。
我发现了几种方法,它们是mod_perl和mod_authnz_external,两者都太慢了,因为只要调用受保护目录中的任何对象,apache就会运行。这意味着用户可能必须在单个会话中进行数百次身份验证。
有没有人设法让Apache使用比MD5和SHA-1更安全的东西而不将身份验证移离Apache?盐渍SHA-2将是一个真正的奖金。
谢谢!
答案 0 :(得分:3)
如果您使用的是在过去5年左右发布的glibc2版本的GNU / Linux系统,您可以修改htpasswd的crypt()实现,将“$ 6 $”添加到salt中,然后再添加就像这样简单:
# htpasswd -d -c .htpasswd someusername
当盐以“$ 6 $”开头时,glibc2将使用盐渍SHA-512,最后16个字符为盐,在[a-zA-Z0-9./].
见man 3 crypt。
我不知道有任何补丁可以支持这个,但它应该是一个简单的补丁。
编辑:我还想提一下,如果你的攻击者足够坚定,那一轮甚至盐腌的SHA-512也是可以破解的。我建议,并且我在大多数情况下都可以使用HMAC-SHA512来编辑128000轮PBKDF2,但这将是一个非常广泛的编辑,除非您想将htpasswd链接到openssl,它有一个PKCS5_PBKDF2_HMAC ()函数。
编辑2:另外,如果你感兴趣的话,使用openssl做强哈希并不难:
abraxas ~ # cat pbkdf2.c
#include <string.h>
#include <stdio.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#define PBKDF2_SALT_PREFIX "$pbkdf2sha512$"
#define PBKDF2_SALT_PREFIX_LENGTH strlen(PBKDF2_SALT_PREFIX)
#define PBKDF2_PRF_ALGORITHM EVP_sha512()
#define PBKDF2_DIGEST_LENGTH SHA512_DIGEST_LENGTH
#define PBKDF2_SALT_LENGTH 32
#define PBKDF2_RESULT_LENGTH PBKDF2_SALT_PREFIX_LENGTH + (2 * PBKDF2_DIGEST_LENGTH) + PBKDF2_SALT_LENGTH + 2
#define PBKDF2_ROUNDS 128000
void hash_password(const char* pass, const unsigned char* salt, char* result)
{
unsigned int i;
static unsigned char digest[PBKDF2_DIGEST_LENGTH];
memcpy(result, PBKDF2_SALT_PREFIX, PBKDF2_SALT_PREFIX_LENGTH);
memcpy(result + PBKDF2_SALT_PREFIX_LENGTH, salt, PBKDF2_SALT_LENGTH);
result[PBKDF2_SALT_PREFIX_LENGTH + PBKDF2_SALT_LENGTH] = '$';
PKCS5_PBKDF2_HMAC(pass, strlen(pass), salt, PBKDF2_SALT_LENGTH, PBKDF2_ROUNDS, PBKDF2_PRF_ALGORITHM, PBKDF2_DIGEST_LENGTH, digest);
for (i = 0; i < sizeof(digest); i++)
sprintf(result + PBKDF2_SALT_PREFIX_LENGTH + PBKDF2_SALT_LENGTH + 1 + (i * 2), "%02x", 255 & digest[i]);
}
int main(void)
{
char result[PBKDF2_RESULT_LENGTH];
char pass[] = "password";
unsigned char salt[] = "178556d2988b6f833f239cd69bc07ed3";
printf("Computing PBKDF2(HMAC-SHA512, '%s', '%s', %d, %d) ...\n", pass, salt, PBKDF2_ROUNDS, PBKDF2_DIGEST_LENGTH);
memset(result, 0, PBKDF2_RESULT_LENGTH);
hash_password(pass, salt, result);
printf("Result: %s\n", result);
return 0;
}
abraxas ~ # gcc -Wall -Wextra -O3 -lssl pbkdf2.c -o pbkdf2
abraxas ~ # time ./pbkdf2
Computing PBKDF2(HMAC-SHA512, 'password', '178556d2988b6f833f239cd69bc07ed3', 128000, 64) ...
Result: $pbkdf2sha512$178556d2988b6f833f239cd69bc07ed3$3acb79896ce3e623c3fac32f91d4421fe360fcdacfb96ee3460902beac26807d28aca4ed01394de2ea37b363ab86ba448286eaf21e1d5b316149c0b9886741a7
real 0m0.320s
user 0m0.319s
sys 0m0.001s
abraxas ~ #