gpt4 book ai didi

error-handling - PKCS5_PBKDF2_HMAC_SHA1返回值是什么意思?

转载 作者:行者123 更新时间:2023-12-02 00:03:56 24 4
gpt4 key购买 nike

我正在尝试使用 OpenSSL 的 PKCS5_PBKDF2_HMAC_SHA1方法。我推测如果成功则返回 0,否则返回一些其他值。我的问题是,非零返回值是什么意思?内存错误?使用错误?我的程序应该如何处理它(重试,退出?)?

编辑:一个必然的问题是,除了对方法本身进行逆向工程之外,还有什么方法可以解决这个问题吗?

最佳答案

is there any way to figure this out besides reverse-engineering the method itself?

PKCS5_PBKDF2_HMAC_SHA1 看起来像是那些未记录的函数之一,因为我在 OpenSSL docs 中找不到它。 。 OpenSSL 有很多这样的库,因此如果您要使用该库,您应该准备好研究源代码。

<小时/>

I gather that it returns 0 if it succeeds, and some other value otherwise.

事实上,情况正好相反。我是这样知道的...

$ grep -R PKCS5_PBKDF2_HMAC_SHA1 *
crypto/evp/evp.h:int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
crypto/evp/p5_crpt2.c:int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
...

因此,您可以在 crypto/evp/p5_crpt2.c 中找到该函数的实现:

int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen,
const unsigned char *salt, int saltlen, int iter,
int keylen, unsigned char *out)
{
return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter,
EVP_sha1(), keylen, out);
}

以下PKCS5_PBKDF2_HMAC:

$ grep -R PKCS5_PBKDF2_HMAC *
...
crypto/evp/evp.h:int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
crypto/evp/p5_crpt2.c:int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
...

再次,来自 crypto/evp/p5_crpt2.c:

int PKCS5_PBKDF2_HMAC(const char *pass, int passlen,
const unsigned char *salt, int saltlen, int iter,
const EVP_MD *digest,
int keylen, unsigned char *out)
{
unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4];
int cplen, j, k, tkeylen, mdlen;
unsigned long i = 1;
HMAC_CTX hctx_tpl, hctx;

mdlen = EVP_MD_size(digest);
if (mdlen < 0)
return 0;

HMAC_CTX_init(&hctx_tpl);
p = out;
tkeylen = keylen;
if(!pass)
passlen = 0;
else if(passlen == -1)
passlen = strlen(pass);
if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL))
{
HMAC_CTX_cleanup(&hctx_tpl);
return 0;
}
while(tkeylen)
{
if(tkeylen > mdlen)
cplen = mdlen;
else
cplen = tkeylen;
/* We are unlikely to ever use more than 256 blocks (5120 bits!)
* but just in case...
*/
itmp[0] = (unsigned char)((i >> 24) & 0xff);
itmp[1] = (unsigned char)((i >> 16) & 0xff);
itmp[2] = (unsigned char)((i >> 8) & 0xff);
itmp[3] = (unsigned char)(i & 0xff);
if (!HMAC_CTX_copy(&hctx, &hctx_tpl))
{
HMAC_CTX_cleanup(&hctx_tpl);
return 0;
}
if (!HMAC_Update(&hctx, salt, saltlen)
|| !HMAC_Update(&hctx, itmp, 4)
|| !HMAC_Final(&hctx, digtmp, NULL))
{
HMAC_CTX_cleanup(&hctx_tpl);
HMAC_CTX_cleanup(&hctx);
return 0;
}
HMAC_CTX_cleanup(&hctx);
memcpy(p, digtmp, cplen);
for(j = 1; j < iter; j++)
{
if (!HMAC_CTX_copy(&hctx, &hctx_tpl))
{
HMAC_CTX_cleanup(&hctx_tpl);
return 0;
}
if (!HMAC_Update(&hctx, digtmp, mdlen)
|| !HMAC_Final(&hctx, digtmp, NULL))
{
HMAC_CTX_cleanup(&hctx_tpl);
HMAC_CTX_cleanup(&hctx);
return 0;
}
HMAC_CTX_cleanup(&hctx);
for(k = 0; k < cplen; k++)
p[k] ^= digtmp[k];
}
tkeylen-= cplen;
i++;
p+= cplen;
}
HMAC_CTX_cleanup(&hctx_tpl);

return 1;
}

因此,失败时看起来像 0,成功时看起来像 1。您不应该看到其他值。如果您得到 0,那么所有 OUT 参数都是垃圾。

<小时/>

Memory error? Usage error?

嗯,有时你可以调用ERR_get_error。如果你调用它并且它有意义,那么错误代码就很好。如果错误代码没有任何意义,那么它可能不好。

遗憾的是,这就是我处理它的方式,因为库与设置错误代码不一致。例如,以下是加载 RDRAND 引擎的库代码。

请注意,如果它是第三代 Ivy Bridge(这是正在测试的功能),代码会在失败时清除错误代码,否则不会清除或设置错误!!!

void ENGINE_load_rdrand (void)
{
extern unsigned int OPENSSL_ia32cap_P[];

if (OPENSSL_ia32cap_P[1] & (1<<(62-32)))
{
ENGINE *toadd = ENGINE_rdrand();
if(!toadd) return;
ENGINE_add(toadd);
ENGINE_free(toadd);
ERR_clear_error();
}
}
<小时/>

How should my program handle it (retry, quit?)?

看起来像是一次严重的失败。

<小时/>

最后,这正是我在这种情况下浏览资源的方式。如果您不喜欢 grep 您可以尝试 ctags或其他源代码浏览器。

关于error-handling - PKCS5_PBKDF2_HMAC_SHA1返回值是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22851828/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com