OpenSSL中的PBKDF2实现

The*_*sor 2 openssl cryptography dev-c++ pbkdf2

我在DevC中使用OpenSSl.我在编程PBKDF时遇到了问题.有人建议我使用名为PKCS5_PBKDF2_HMAC的默认函数.我在网上访问了很多链接,但无法使用它.我的主要代码()代码如下

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);
Run Code Online (Sandbox Code Playgroud)

我只有两个编译错误,如下所示:

  • 功能'PKCS5_PBKDF2_HMAC'参数太少
  • 'EVP_MD'之前的预期表达式

要进行故障排除我检查了头文件并且还验证了我提供了正确的参数并且顺序正确,但我没有解决方案而且我感到困惑.

Ant*_*rds 7

你有一些重大错误,但这个想法很扎实.

  • EVP_*需要是一个特定的功能.

  • keylen = 128是密码散列的错误,您的示例似乎是.不要忘记 - 从不要求比本机哈希函数支持更多(二进制)字节的输出,因为那时你正在进行迭代计数*(keylen/native hash size)次数,并且攻击者只需要进行迭代计数*1次.

    • SHA-1为20

    • SHA-224为28

    • 32为SHA-256

    • SHA-384为48

    • 对于SHA-512,为64

  • 结果[1024]太大了.结果[keylen]是正确的.

  • 如果有人输入超过1024个字节,请注意缓冲区溢出.

我在我的Github存储库(以及PolarSSL和其他各种)中有OpenSSL PBKDF2示例代码,但关键的例子是(使用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];
      };

}
Run Code Online (Sandbox Code Playgroud)

它将被称为:

 // 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);
Run Code Online (Sandbox Code Playgroud)

尝试使用SHA-384或SHA-512作为基本哈希函数; 它们包括64位操作,可以减少大多数基于GPU的攻击者的优势.

使用大量(数十万到数万)次迭代.SHA-1甚至更大.

我的Github存储库中还有一个很大的测试向量列表- 您可以使用它们来验证您的代码是否返回了它应该返回的结果.


adl*_*lag 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;
}
Run Code Online (Sandbox Code Playgroud)