2016-02-13 31 views
1

我在DevC中使用OpenSSl。我在編程PBKDF時遇到了問題。有人建議我使用名爲PKCS5_PBKDF2_HMAC的默認功能。我在網上訪問了許多聯繫,但無法從主(得到這個work.My代碼)如下在OpenSSL中實現PBKDF2

unsigned char pass[1024];  // passphrase read from stdin 
unsigned char salt[1024];  // salt 
int iter=1000, keylen=128;  // iteration 
unsigned char result[1024]; // result 
PKCS5_PBKDF2_HMAC (pass, strlen(pass), salt, strlen(salt), iter, EVP_MD(), keylen , result); 

我有隻有兩個編譯錯誤如下:

  • 參數太少函數「PKCS5_PBKDF2_HMAC」
  • 預期的表達「EVP_MD」

要解決之前,我檢查了頭文件,也驗證了我提供正確的參數d按照正確的順序,但我沒有解決辦法,我只是感到困惑。

+1

請注意,您不應使用該尺寸的鹽。您應該只在表示以空字符結尾的字符數組上使用'strlen',而不是數組。 –

+1

@Professor:*「我只有兩個編譯錯誤,如下所示......」 - 請複製並粘貼您收到的* exact *錯誤消息,包括編譯器用於指示問題表達式的小刻度標記。你的'pass'和'salt'是非空間垃圾。 'keylen'應該是字節,而不是位。 – jww

回答

0

以下單位編譯並給出了RFC6070所需的結果。

#include <openssl/evp.h> 
#include <iostream> 

enum { KEYLENGTH = 16 }; 

int main(int argc, char *argv[]) 
{ 
    char pass[]="pass\0word"; 
    unsigned char salt[] = "sa\0lt"; 
    int iter=4096; 
    unsigned char result[KEYLENGTH]; 
    int success = PKCS5_PBKDF2_HMAC (pass, sizeof(pass) -1, salt, sizeof(salt)-1, iter, EVP_sha1(), KEYLENGTH , result); 
    // catch success == 0  
    // using Qt for quick outputting 
    QByteArray resultBytes((char*)result,KEYLENGTH); 
    QByteArray resultHex = resultBytes.toHex(); 
    std::cout << resultHex.data(); 
    // will output 56fa6aa75548099dcc37d7f03425e0c3 
    return 0; 
} 
+0

感謝您的回覆。我遇到了一些由於沒有zlib庫而導致的錯誤。安裝了這個,並結束了一些新的錯誤,如:未定義的引用'CreateDCA @ 16' –

5

你有一些重大錯誤,但這個想法是可靠的。

  • EVP_ *需要是特定的功能。

  • keylen = 128是密碼哈希的錯誤,您的示例似乎是。不要忘記 - 永遠不要求比本機散列函數支持更多(二進制)的輸出字節,因爲那麼你的迭代次數*(keylen /本地散列大小)是次數,攻擊者只需要做迭代計數* 1次。

    • 20 SHA-1

    • 28 SHA-224

    • 32 SHA-256

    • 48 SHA-384

    • 64,用於SHA -512

  • 結果[1024]太大了。結果[keylen]是正確的。

  • 當心緩衝區溢出,如果有人把超過1024個字節英寸

我在my Github repository OpenSSL的PBKDF2示例代碼(以及PolarSSL和各種其他的),但重要的例子將(使用PBKDF2-HMAC-SHA-512,作爲最佳的選擇):

void PBKDF2_HMAC_SHA_512(const char* pass, const unsigned char* salt, int32_t iterations, uint32_t outputBytes, char* hexResult, uint8_t* binResult) 
{ 
    unsigned int i; 
    unsigned char digest[outputBytes]; 
    PKCS5_PBKDF2_HMAC(pass, strlen(pass), salt, strlen(salt), iterations, EVP_sha512(), outputBytes, digest); 
    for (i = 0; i < sizeof(digest); i++) 
     { 
     sprintf(hexResult + (i * 2), "%02x", 255 & digest[i]); 
     binResult[i] = digest[i]; 
     }; 

} 

而且,它還將被稱爲:

// 2*outputBytes+1 is 2 hex bytes per binary byte, and one character at the end for the string-terminating \0 
    char hexResult[2*outputBytes+1]; 
    memset(hexResult,0,sizeof(hexResult)); 
    uint8_t binResult[outputBytes]; 
    memset(hexResult,0,sizeof(binResult)); 

PBKDF2_HMAC_SHA_512(pass, salt, iterations, outputBytes, hexResult, binResult); 

嘗試使用SHA-384或SHA-512作爲基準散列函數;它們包括64位操作,可以減少大多數基於GPU的攻擊者的優勢。

使用大量(數十萬次到數萬次)的迭代次數。 SHA-1甚至更大。

我也有一個大的列表test vectors in my Github repository - 你可以使用它們來驗證你的代碼是否返回它應該的結果。