RSA 签名:OpenSSL

发布于 2024-10-22 05:16:41 字数 2471 浏览 1 评论 0原文

我正在尝试使用 Openssl 的 EVP 接口进行编码,以使用 SHA1 进行 RSA 签名。后来我想用不同的摘要算法和不同的签名算法(或者通用的,因此使用 EVP)来扩展签名。

每当我尝试检索私钥的大小时,我似乎都会遇到分段错误

有人可以告诉我如何纠正这个问题吗?

int rsaSign(char *in_file, char * sig_file){

        char *data = NULL;
        int data_len;
        unsigned int sig_len;
        unsigned char *sig;
        int err = -1;

        OpenSSL_add_all_digests();
        FILE *fd;
        EVP_PKEY *priv_key = EVP_PKEY_new();
        RSA *privkey = NULL;
           printf( "we are here..\n");

        if ((fd = fopen(PRIVKEY_FILE, "r")) == NULL){
            printf("error reading file\n");
            exit(0);
        }

        privkey = RSA_new();
        if (!PEM_read_PrivateKey(fd, &privkey, NULL, NULL))
        {
            fprintf(stderr, "Error loading RSA Private Key File.\n");
            return 2;
        }

        fclose(fd);

        if (!EVP_PKEY_assign_RSA (priv_key, privkey))
        {
            fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n");
            return 3;
        }

        if (!priv_key) {
            printf("no private key\n");
        }
        EVP_PKEY_set1_RSA(privkey, priv_key);


        EVP_MD_CTX *ctx = EVP_MD_CTX_create();

        const EVP_MD *md = EVP_get_digestbyname("SHA1");

        if (!md) {
            fprintf(stderr, "Error creating message digest");
            fprintf(stderr, " object, unknown name?\n");
            ERR_print_errors_fp(stderr);
            exit(1);
        }



        if (!EVP_SignInit(ctx, md))
            {
                fprintf(stderr, "EVP_SignInit: failed.\n");
                EVP_PKEY_free(priv_key);
                return 3;
            }
        printf( "now to sign update..\n");
        data = readFile(in_file);
        data_len = strlen(data);
        printf("data len = %d\n", data_len);

        if (!EVP_SignUpdate(ctx, data, data_len))
        {
            fprintf(stderr, "EVP_SignUpdate: failed.\n");
            EVP_PKEY_free(priv_key);
            return 3;
        }
        printf( "now to sign final..\n");

sig = malloc(EVP_PKEY_size(privkey)); //!!!!! SEGMENTATION FAULT HERE !!!!!


        if (!EVP_SignFinal(ctx, &sig, &sig_len, priv_key))
        {
            fprintf(stderr, "EVP_SignFinal: failed.\n");
            free(sig);
            EVP_PKEY_free(priv_key);
            return 3;
        }

        free(data);
        free(sig);
        EVP_PKEY_free(priv_key);
        return EXIT_SUCCESS;

}

I am trying to code with EVP interface of Openssl for RSA signing with SHA1. Later I would like to expand signing with different digest algorithms and different signature algorithms(sor of generic, and therefore the use of EVP).

I seem to get a segmentation fault whenever I try to retrieve the size of my private key

Can someone tell me how to correct this?

int rsaSign(char *in_file, char * sig_file){

        char *data = NULL;
        int data_len;
        unsigned int sig_len;
        unsigned char *sig;
        int err = -1;

        OpenSSL_add_all_digests();
        FILE *fd;
        EVP_PKEY *priv_key = EVP_PKEY_new();
        RSA *privkey = NULL;
           printf( "we are here..\n");

        if ((fd = fopen(PRIVKEY_FILE, "r")) == NULL){
            printf("error reading file\n");
            exit(0);
        }

        privkey = RSA_new();
        if (!PEM_read_PrivateKey(fd, &privkey, NULL, NULL))
        {
            fprintf(stderr, "Error loading RSA Private Key File.\n");
            return 2;
        }

        fclose(fd);

        if (!EVP_PKEY_assign_RSA (priv_key, privkey))
        {
            fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n");
            return 3;
        }

        if (!priv_key) {
            printf("no private key\n");
        }
        EVP_PKEY_set1_RSA(privkey, priv_key);


        EVP_MD_CTX *ctx = EVP_MD_CTX_create();

        const EVP_MD *md = EVP_get_digestbyname("SHA1");

        if (!md) {
            fprintf(stderr, "Error creating message digest");
            fprintf(stderr, " object, unknown name?\n");
            ERR_print_errors_fp(stderr);
            exit(1);
        }



        if (!EVP_SignInit(ctx, md))
            {
                fprintf(stderr, "EVP_SignInit: failed.\n");
                EVP_PKEY_free(priv_key);
                return 3;
            }
        printf( "now to sign update..\n");
        data = readFile(in_file);
        data_len = strlen(data);
        printf("data len = %d\n", data_len);

        if (!EVP_SignUpdate(ctx, data, data_len))
        {
            fprintf(stderr, "EVP_SignUpdate: failed.\n");
            EVP_PKEY_free(priv_key);
            return 3;
        }
        printf( "now to sign final..\n");

sig = malloc(EVP_PKEY_size(privkey)); //!!!!! SEGMENTATION FAULT HERE !!!!!


        if (!EVP_SignFinal(ctx, &sig, &sig_len, priv_key))
        {
            fprintf(stderr, "EVP_SignFinal: failed.\n");
            free(sig);
            EVP_PKEY_free(priv_key);
            return 3;
        }

        free(data);
        free(sig);
        EVP_PKEY_free(priv_key);
        return EXIT_SUCCESS;

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一指流沙 2024-10-29 05:16:41

您有几个问题:

  • PEM_read_PrivateKey() 需要 EVP_PKEY **,而不是 RSA ** - 事实上,您不需要 < code>RSA * 对象;
  • 您不应该调用 EVP_PKEY_assign_RSA()
  • 您不应调用 EVP_PKEY_set1_RSA()

要加载私钥,您只需执行以下操作:

EVP_PKEY *priv_key = NULL;

if (!PEM_read_PrivateKey(rsa_pkey_file, &priv_key, NULL, NULL))
{
    fprintf(stderr, "Error loading Private Key File.\n");
    return 2;
}

您现在可以调用 EVP_PKEY_size(priv_key) 来确定密钥大小。

此外,您的 EVP_SignFinal() 调用是错误的 - 您应该传递 sig,而不是 &sig

You have several problems:

  • PEM_read_PrivateKey() expects an EVP_PKEY **, not an RSA ** - in fact, you do not need an RSA * object at all;
  • You should not be calling EVP_PKEY_assign_RSA();
  • You should not be calling EVP_PKEY_set1_RSA().

To load the private key, you can simply do:

EVP_PKEY *priv_key = NULL;

if (!PEM_read_PrivateKey(rsa_pkey_file, &priv_key, NULL, NULL))
{
    fprintf(stderr, "Error loading Private Key File.\n");
    return 2;
}

You may now call EVP_PKEY_size(priv_key) to determine the key size.

Additionally, your EVP_SignFinal() call is wrong - you should be passing sig, not &sig.

栩栩如生 2024-10-29 05:16:41

我不是该特定库的专家,但仔细阅读了 API 文档后,我认为:

EVP_PKEY_set1_RSA(privkey, priv_key);

应该是:

EVP_PKEY_set1_RSA(priv_key, privkey);

同样,您突出显示为 SEGFAULTing 的行不应该引用 priv_key 而不是 privkey 另外:

sig = malloc(EVP_PKEY_size(priv_key));

如果将变量名称更改为更容易区分的名称(而不是 privkeypriv_key,请使用 < code>priv_key_RSA 和 priv_key_EVP

拥有仅下划线不同的变量是一个非常坏主意:)

I'm no expert in that particular library, but having perused the API docs, I think this:

EVP_PKEY_set1_RSA(privkey, priv_key);

should be:

EVP_PKEY_set1_RSA(priv_key, privkey);

and similarly shouldn't the line you've highlighted as SEGFAULTing refer to priv_key not privkey also:

sig = malloc(EVP_PKEY_size(priv_key));

Both these mistakes would be easier to see if you change your variable names to something easier to distinguish (rather than privkey and priv_key, use priv_key_RSA and priv_key_EVP

Having variables which differ only in their underscores is a really bad idea :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文