jtp*_*yda 5 openssl cryptography pbkdf2
我想利用SHA1 HMAC的PBKDF2算法(基于这个答案).
如何通过加密库来利用它?
我开始看man openssl
,但openssl passwd
命令(手册页)只支持少量算法.查看加密文档,evp模块具有EVP_BytesToKey方法.
仔细选择参数将提供PKCS#5 PBKDF1兼容的实现.但是,新应用程序通常不应使用此功能(例如,首选PCKS#5的PBKDF2).
这让我回到原来的问题,如何通过加密利用PBKDF2?我是否需要深入研究代码并调用非API公开的方法(例如PKCS5_PBKDF2_HMAC)?(如果是的话,是什么让它不被暴露?)
通过我的github存储库中的OpenSSL库,我确实有一个工作但很差的C的PBKDF2示例,包括在Linux和Windows(通过MinGW)下编译的脚本.位于"Releases"下的源代码已知良好; 主分支中的源代码是WIP.除了SSLeay许可证OpenSSL之外,此变体还在相同的4条款BSD下获得许可.
我还在努力添加一些功能,然后我将回到Code Review StackExchange网站上的优秀输入并升级到C99语法等等.
核心代码非常原始,尽管传递了非常广泛的基于字符串的测试向量,但可能包含缺陷.它尚未针对纯二进制输入进行测试.
#include <openssl/evp.h>
#include <openssl/sha.h>
// crypto.h used for the version
#include <openssl/crypto.h>
void PBKDF2_HMAC_SHA_1nat_string(const char* pass, const unsigned char* salt, int32_t iterations, uint32_t outputBytes, char* hexResult)
{
unsigned int i;
unsigned char digest[outputBytes];
PKCS5_PBKDF2_HMAC_SHA1(pass, strlen(pass), salt, strlen(salt), iterations, outputBytes, digest);
for (i = 0; i < sizeof(digest); i++)
sprintf(hexResult + (i * 2), "%02x", 255 & digest[i]);
}
Run Code Online (Sandbox Code Playgroud)
如果您有64位系统,我强烈建议您转而使用PBKDF2-HMAC-SHA-512或PBKDF2-HMAC-SHA-384:
#include <openssl/evp.h>
#include <openssl/sha.h>
// crypto.h used for the version
#include <openssl/crypto.h>
void PBKDF2_HMAC_SHA_384_string(const char* pass, const unsigned char* salt, int32_t iterations, uint32_t outputBytes, char* hexResult)
{
unsigned int i;
unsigned char digest[outputBytes];
PKCS5_PBKDF2_HMAC(pass, strlen(pass), salt, strlen(salt), iterations, EVP_sha384(), outputBytes, digest);
for (i = 0; i < sizeof(digest); i++)
sprintf(hexResult + (i * 2), "%02x", 255 & digest[i]);
}
void PBKDF2_HMAC_SHA_512_string(const char* pass, const unsigned char* salt, int32_t iterations, uint32_t outputBytes, char* hexResult)
{
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]);
}
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));
PBKDF2_HMAC_SHA_1nat_string(pass, salt, iterations, outputBytes, hexResult);
printf("%s\n", hexResult);
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));
PBKDF2_HMAC_SHA_512_string(pass, salt, iterations, outputBytes, hexResult);
printf("%s\n", hexResult);
Run Code Online (Sandbox Code Playgroud)
使用8到16个二进制字节的随机,每用户盐,即16到32个十六进制数字 - 我的代码没有生成这个的例子
无论你选择什么,一定要根据测试向量进行验证(少数在我的存储库中的pbkdf2_test.bat/sh中).
此外,在您的系统上,进行一些基准测试 - 当然在PBKDF2-HMAC-SHA-384和PBKDF2-HMAC-SHA-512变体上,在64位系统下进行编译可以产生显着更好的结果.将它与我同样糟糕的C++ Crypto ++和/或我糟糕的C PolarSSL示例或Jither的C#实现示例进行比较,具体取决于您的目标系统.
您关心速度的原因是您必须根据生产系统可用的性能与在高峰时间登录/创建密码的用户数量选择迭代计数,以免产生太多缓慢的抱怨.
攻击者会使用类似oclHashcat,其中,8倍AMD R9 290Xstock核心时钟在一台PC上能够尝试3.4E12(2 ^ 41)对PBKDF2-HMAC-SHA-1每30天猜测(SSID盐,密码,32字节输出长度,4096次迭代,又名WPA/WPA2),它或多或少等同于PBKDF2-HMAC-SHA-1(盐,pw,20字节输出长度,8192次迭代).
当攻击者开始选择攻击时,差异变得很重要.
现在,对于PBKDF2,还有一些其他的事情要知道:
归档时间: |
|
查看次数: |
14108 次 |
最近记录: |