OpenSSL中PBKDF2的实现

OpenSSL中PBKDF2的实现,openssl,cryptography,dev-c++,pbkdf2,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

我在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);
我只有两个编译错误,如下所示:

  • 函数“PKCS5_PBKDF2_HMAC”的参数太少
  • “EVP_MD”之前的预期表达式

为了排除故障,我检查了头文件,并验证了我提供的参数是否正确,顺序是否正确,但我没有解决方案,只是感到困惑。

以下单元编译并给出了所需的结果

#包括
#包括
枚举{KEYLENGTH=16};
int main(int argc,char*argv[])
{
char pass[]=“pass\0word”;
无符号字符salt[]=“sa\0lt”;
国际热核实验堆=4096;
无符号字符结果[KEYLENGTH];
int success=PKCS5_PBKDF2_HMAC(pass,sizeof(pass)-1,salt,sizeof(salt)-1,iter,EVP_sha1(),KEYLENGTH,result);
//捕获成功==0
//使用Qt进行快速输出
QByteArray结果字节((char*)结果,KEYLENGTH);
QByteArray resultHex=resultBytes.toHex();

std::cout你有一些重大错误,但想法是可靠的

  • EVP_*需要是一个特定的函数

  • keylen=128对于密码散列来说是一个错误,您的示例就是这样。不要忘记-永远不要要求比本机散列函数支持的更多(二进制)字节的输出,因为这样您就进行了迭代计数*(keylen/本机散列大小)次,而攻击者只需要进行迭代计数*1次

    • SHA-1为20

    • SHA-224为28

    • SHA-256为32

    • SHA-384为48

    • SHA-512为64

  • 结果[1024]太大。结果[keylen]正确

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

我有OpenSSL PBKDF2示例代码(以及PolarSSL和其他各种代码),但关键示例是(使用PBKDF2-HMAC-SHA-512作为最佳选项):

尝试使用SHA-384或SHA-512作为基本散列函数;它们包括64位操作,减少了大多数基于GPU的攻击者相对于您的优势

使用大量(数十万到数万)的迭代。对于SHA-1,迭代次数甚至更大


我还有一个很大的列表-您可以使用它们来验证您的代码是否返回了它应该返回的结果。

注意,您不应该使用这种大小的salt。您应该只在表示以null结尾的字符串而不是数组的字符数组上使用
strlen
。@Professor:“我只有两个编译错误,如下所示…”-请复制并粘贴您收到的确切错误消息,包括编译器用于指示问题表达式的小记号。您的
pass
salt
都是未初始化的垃圾。
keylen
应该是字节,而不是位。感谢您的回复。我遇到了一些错误,这些错误是由于缺少zlib库。安装了该库后,出现了一些新错误,如:未定义对的引用`CreateDCA@16'
#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;
}
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);