OpenSSL 3.0启用FIPS时EVP_PKEY_CTX_new_id(EVP_PKEY_SCRYPT,e)返回NULL求替代方案
OpenSSL 3.0 FIPS模式下scrypt替代方案
问题原因
OpenSSL 3.0的FIPS合规模式仅支持FIPS 140-3批准的算法集合,scrypt不在此列表中,因此启用FIPS后,scrypt相关的EVP_PKEY接口会被禁用,导致EVP_PKEY_CTX_new_id(EVP_PKEY_SCRYPT, e)返回NULL。
方案一:使用FIPS批准的PBKDF2算法替代
PBKDF2是FIPS认证的密钥派生算法,可直接在OpenSSL FIPS环境下运行,实现等效的密码哈希功能。替换代码如下:
#include <openssl/evp.h> #include <sstream> #include <iomanip> #include <string> using namespace std; string pbkdf2_hashing(string sPassword, string sSalt, int iIterations, int dkLen = 64) { unsigned char out[64]; size_t outlen = dkLen; // 采用PBKDF2-HMAC-SHA512算法(FIPS合规) if (PKCS5_PBKDF2_HMAC(sPassword.c_str(), sPassword.size(), reinterpret_cast<const unsigned char*>(sSalt.c_str()), sSalt.size(), iIterations, EVP_sha512(), outlen, out) != 1) { error("PKCS5_PBKDF2_HMAC failed"); } stringstream ss; ss << hex << setfill('0'); for (int i = 0; i < outlen; ++i) { ss << setw(2) << static_cast<int>(out[i]); } return ss.str(); }
注意:需根据安全需求调整迭代次数,建议设置为100000次以上,以匹配scrypt的抗暴力破解强度。
方案二:使用独立scrypt库实现
若必须保留scrypt算法,可使用不依赖OpenSSL的第三方scrypt库(如libscrypt),绕过OpenSSL FIPS模式的限制。示例代码如下:
#include <scrypt.h> #include <sstream> #include <iomanip> #include <string> using namespace std; string scrypt_hashing_lib(string sPassword, string sSalt, int iN, int iR, int iP) { unsigned char out[64]; size_t outlen = sizeof(out); // 调用libscrypt的原生scrypt实现 if (scrypt(reinterpret_cast<const unsigned char*>(sPassword.c_str()), sPassword.size(), reinterpret_cast<const unsigned char*>(sSalt.c_str()), sSalt.size(), iN, iR, iP, out, outlen) != 0) { error("scrypt failed"); } stringstream ss; ss << hex << setfill('0'); for (int i = 0; i < outlen; ++i) { ss << setw(2) << static_cast<int>(out[i]); } return ss.str(); }
该方案保留了scrypt的算法特性,但需要额外引入并编译libscrypt库。
内容的提问来源于stack exchange,提问作者Antarus
相关产品推荐
相关产品推荐

