【问题标题】:PBKDF2 implementation in OpenSSLOpenSSL 中的 PBKDF2 实现
【发布时间】:2016-05-24 17:06:03
【问题描述】:

我在 DevC 中使用 OpenSSl。我在编写 PBKDF 时遇到问题。有人建议我使用名为 PKCS5_PBKDF2_HMAC 的默认函数。我已经访问了许多在线链接,但无法使其正常工作。我的 main() 代码如下

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”之前的预期表达式

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

【问题讨论】:

  • 请注意,您不应使用这种大小的盐。你应该只在代表空终止字符串的字符数组上使用strlen,而不是数组。
  • @Professor:“我只有两个编译错误,如下所示……” - 请复制并粘贴您的exact错误消息正在接收,包括编译器用来指示问题表达式的小刻度线。您的 passsalt 是未初始化的垃圾。 keylen 应该是字节,而不是位。

标签: openssl cryptography dev-c++ pbkdf2


【解决方案1】:

你有一些重大错误,但这个想法是可靠的。

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

  • keylen=128 是密码散列的错误,您的示例似乎是这样。不要忘记 - 永远不要要求比本机散列函数支持更多的(二进制)字节输出,因为那样你正在做你的迭代计数 *(keylen / 本机散列大小)次,攻击者只需要做迭代计数* 1 次。

    • SHA-1 为 20

    • SHA-224 为 28

    • SHA-256 为 32

    • SHA-384 为 48

    • SHA-512 为 64

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

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

我在my Github repository(以及 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];
      };

}

它会被调用:

 // 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 列表 - 您可以使用它们来验证您的代码是否返回了应有的结果。

【讨论】:

    【解决方案2】:

    以下单元编译并给出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;
    }
    

    【讨论】:

    • 感谢您的回复。由于缺少 zlib 库,我遇到了许多错误。安装了这个并出现了一些新错误,例如: undefined reference to `CreateDCA@16'
    猜你喜欢
    • 1970-01-01
    • 2018-11-05
    • 2011-12-11
    • 2012-07-22
    • 2011-05-29
    • 2010-11-06
    • 2023-02-23
    • 2014-05-12
    • 1970-01-01
    相关资源
    最近更新 更多