使用Apache进行快速SHA-2身份验证,甚至可能吗?

时间:2012-04-09 00:32:27

标签: apache sha256 sha2 mod-auth

好的,我花了最近几天研究这个,我不相信Apache本身支持的散列函数已经过时了。

我发现了几种方法,它们是mod_perl和mod_authnz_external,两者都太慢了,因为只要调用受保护目录中的任何对象,apache就会运行。这意味着用户可能必须在单个会话中进行数百次身份验证。

有没有人设法让Apache使用比MD5和SHA-1更安全的东西而不将身份验证移离Apache?盐渍SHA-2将是一个真正的奖金。

谢谢!

1 个答案:

答案 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 ~ #