Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C RSA标志:OpenSSL_C_Openssl - Fatal编程技术网

C RSA标志:OpenSSL

C RSA标志:OpenSSL,c,openssl,C,Openssl,我正在尝试使用Openssl的EVP接口编写代码,用于使用SHA1进行RSA签名。稍后,我想用不同的摘要算法和不同的签名算法(sor的泛型,因此EVP的使用)来扩展签名 每当我试图检索私钥的大小时,似乎都会出现分段错误 有人能告诉我怎么改正吗 int rsaSign(char *in_file, char * sig_file){ char *data = NULL; int data_len; unsigned int sig_len;

我正在尝试使用Openssl的EVP接口编写代码,用于使用SHA1进行RSA签名。稍后,我想用不同的摘要算法和不同的签名算法(sor的泛型,因此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;

}

我不是该库的专家,但仔细阅读了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));
如果您将变量名更改为更容易区分的名称(而不是
privkey
privkey
,使用
privkey\u RSA
privkey\u EVP


只有下划线不同的变量是一个非常糟糕的主意:)

您有几个问题:

  • PEM_read_PrivateKey()
    需要一个
    EVP_PKEY**
    ,而不是
    RSA**
    ——事实上,您根本不需要
    RSA*
    对象
  • 您不应该调用
    EVP\u PKEY\u assign\u RSA()
  • 您不应该调用
    EVP\u PKEY\u set1\u 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\u PKEY\u size(priv\u key)
来确定密钥大小


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

您可以添加从EVP\u PKEY\u size()返回的大小吗?