2012-04-09 126 views
0

好吧,我花了最近幾天研究這一點,我無法相信Apache本身支持的散列函數已經過時了。使用Apache進行快速SHA-2身份驗證,甚至有可能嗎?

我發現了一些方法來做到這一點,這兩個方法是mod_perl和mod_authnz_external,它們都太慢了,因爲只要調用受保護目錄內的任何對象,apache就會運行該方法。這意味着用戶可能必須在單個會話中進行數百次驗證。

有沒有人設法讓Apache使用比MD5和SHA-1更安全的東西,而無需將認證從Apache移開?醃製的SHA-2將是一個真正的獎勵。

謝謝!

回答

3

如果你使用的是過去5年左右發佈的glibc2版本的GNU/Linux系統,你可以修改htpasswd的crypt()實現,在salt中加上$ 6 $, d是簡單的:

# htpasswd -d -c .htpasswd someusername 

當鹽與「$ 6個$」開始,glibc2的將使用鹽醃SHA-512,與最多16個字符作爲鹽,在範圍[A-ZA後-Z0-9./。

查看man 3 crypt。

我不知道有任何補丁支持這個,但它應該是一個簡單的補丁。

編輯:我也想提一下,如果你的攻擊者足夠認定,那麼即使是醃製SHA-512的一輪也是易碎的。我建議,並且在我已經能夠編輯的大多數事情中使用了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 ~ # 
+0

在我的機器(Ubuntu的16.04),我必須安裝'的libssl-dev',明顯。然後,我不得不使用不同的編譯命令來成功構建:'gcc -Wall -Wextra -O3 pbkdf2.c -o pbkdf2 -lcrypto' – 2017-03-09 22:20:51