gpt4 book ai didi

openssl - 如何中止 RSA_generate_key?

转载 作者:行者123 更新时间:2023-12-02 10:34:54 27 4
gpt4 key购买 nike

考虑以下 RSA_generate_key() 调用:

RSA * rsa = RSA_generate_key(8192, RSA_F4, NULL, NULL);

生成 8,192 位 RSA key 可能需要很长时间(从几秒到几分钟不等)。假设包含上述代码行的应用程序为用户提供了一个取消 key 生成的按钮。

如何在生成 key 之前中止计算并使函数返回?我记得 RSA_generate_key() 的第三个参数是一个用于显示进度的回调函数 - 回调是否可以返回一个表示“中止操作并返回”的值?

不能在另一个线程中运行该函数,然后终止该线程。

最佳答案

由于 RSA_generate_key 提供了进度回调,因此您可以使用 longjmp 来终止该函数。通过一些额外的代码,您可以为 RSA_generate_key 创建一个包装器,它接受通用测试函数,该函数可用于检查窗口系统设置的超时或标志。

#include <openssl/rsa.h>
#include <stdbool.h>
#include <setjmp.h>

struct trampoline_ctx {
bool (*testfn)(void *);
void *testfn_arg;
jmp_buf env;
};

static void trampoline(int ignore1, int ignore2, void *arg)
{
struct trampoline_ctx *ctx = arg;
if (!ctx->testfn(ctx->testfn_arg))
longjmp(ctx->env, 1);
}

// like RSA_generate_key, but accepts a test function. If testfn returns
// false, key generation is terminated and NULL is returned.
RSA *
my_generate_key(int num, unsigned long e,
bool (*testfn)(void *), void *testfn_arg)
{
struct trampoline_ctx ctx;
ctx.testfn = testfn;
ctx.testfn_arg = testfn_arg;
if (setjmp(ctx.env))
return NULL;
return RSA_generate_key(num, e, trampoline, &ctx);
}

这种方法具有惊人的可移植性,因为 longjmp 是 C89 和 C99 都强制要求的。它的缺点是,如果您要跳出的函数动态分配资源,它可能会泄漏资源。然而,实际上,如果不经常执行或仅根据明确的用户请求执行,泄漏可能足够小,以至于不易察觉。为了确定这种情况,请在紧密循环中运行代码并观察进程的资源消耗。

下面是上述功能的测试程序:

#include <stdio.h>
#include <sys/time.h>

double now()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + (double) tv.tv_usec / 1e6;
}

struct tt_ctx {
double start;
double limit;
};

bool test_time_limit(void *arg)
{
struct tt_ctx *ctx = arg;
return now() - ctx->start <= ctx->limit;
}

int main(int argc, char **argv)
{
int limit = atoi(argv[1]);
struct tt_ctx ctx;
ctx.start = now();
ctx.limit = limit / 1000.0;

RSA *key = my_generate_key(4096, 65537, test_time_limit, &ctx);
printf("%p\n", key);
return 0;
}

测试程序假定 POSIX gettimeofday,但可以轻松转换为系统提供的另一个高分辨率时钟。测试流程如下:

将两段代码附加到文件中并使用-lrsa进行编译。测试程序将在命令行指定的以毫秒为单位的时间限制内生成 4096 位 RSA key 。在所有情况下,它都会打印生成的 RSA * 指针,以指示 my_generate_key 是否完成其请求或已中止。 time 的输出伴随着执行作为健全性检查,以验证时间限制是否得到遵守:

# try with a 10ms limit
$ time ./a.out 10
(nil) # too short
./a.out 10 0.02s user 0.00s system 85% cpu 0.023 total

# see if 100ms is enough time
$ time ./a.out 100
(nil) # still too short
./a.out 100 0.10s user 0.00s system 97% cpu 0.106 total

# try with 1 whole second:
$ time ./a.out 1000
0x2369010 # success!
./a.out 1000 0.64s user 0.00s system 99% cpu 0.649 total

关于openssl - 如何中止 RSA_generate_key?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15183101/

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