Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.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 openssl未正确验证签名_C_Openssl_Rsa - Fatal编程技术网

C openssl未正确验证签名

C openssl未正确验证签名,c,openssl,rsa,C,Openssl,Rsa,遵循OpenSSL文档,我认为我所做的是正确的。。但显然不是。编译文件(使用gcc-g-Wall-Wextra-lssl sign.c)不会产生错误或警告EVP\u VerifyFinal()始终返回0(表示检查失败)。是什么原因造成的 static const EVP_MD * type; unsigned char * sha(char * input) { EVP_MD_CTX c; unsigned char *md; unsigned int md_len;

遵循OpenSSL文档,我认为我所做的是正确的。。但显然不是。编译文件(使用gcc-g-Wall-Wextra-lssl sign.c)不会产生错误或警告
EVP\u VerifyFinal()
始终返回0(表示检查失败)。是什么原因造成的

static const EVP_MD * type;

unsigned char * sha(char * input)
{
    EVP_MD_CTX c;
    unsigned char *md;
    unsigned int md_len;

    md = malloc(EVP_MAX_MD_SIZE);

    EVP_MD_CTX_init(&c);
    EVP_DigestInit_ex(&c, type, NULL);
    EVP_DigestUpdate(&c, input, strlen(input));
    EVP_DigestFinal_ex(&c, md, &md_len); 
    EVP_MD_CTX_cleanup(&c);

    return md;
}

unsigned char * sign(EVP_PKEY * key, unsigned char * data)
{
    EVP_MD_CTX c;
    unsigned char *sig;
    unsigned int len;

    EVP_MD_CTX_init(&c);
    sig = malloc(EVP_PKEY_size(key));

    EVP_SignInit(&c, type);
    EVP_SignUpdate(&c, data, strlen((char *)data));
    EVP_SignFinal(&c, sig, &len, key);

    EVP_MD_CTX_cleanup(&c);

    return sig;
}

int verify(EVP_PKEY * key, unsigned char * data, unsigned char * original)
{
    EVP_MD_CTX c;
    int ret;

    EVP_MD_CTX_init(&c);
    EVP_VerifyInit(&c, type);
    EVP_VerifyUpdate(&c, data, (unsigned int)sizeof(data));
    ret = EVP_VerifyFinal(&c, original, (unsigned int)strlen((char *)original), key);
    return ret;
}

int main(void)
{
    EVP_PKEY *sk, *pk;
    FILE *sfd, *pfd;
    unsigned char *hash, *sig;
    unsigned int i;

    sfd = fopen("secret.pem", "r");
    pfd = fopen("public.pem", "r");
    sk = PEM_read_PrivateKey(sfd, NULL, NULL, NULL);
    pk = PEM_read_PUBKEY(pfd, NULL, NULL, NULL);
    fclose(sfd);
    fclose(pfd);

    OpenSSL_add_all_digests();
    type = EVP_get_digestbyname("SHA1");

    hash = sha("moo");

    for(i = 0; i < sizeof(hash); i++)
        printf("%02x", hash[i]);
    printf("\n");

    sig = sign(sk, hash);
    switch( verify(pk, sig, hash) )
    {
        case 0:
            printf("Check failed.\n");
            break;
        case 1:
            printf("Check succeeded!\n");
            break;
        default:
            printf("Oh look, an error: %d", ERR_get_error());
            break;
    }

    return 0;
}
static const EVP_MD*类型;
无符号字符*sha(字符*input)
{
执行副总裁MD CTX c;
无符号字符*md;
无符号整数md_len;
md=malloc(EVP\u最大\u md\u尺寸);
执行副总裁MD CTX初始(&c);
EVP_DigestInit_ex(&c,类型,NULL);
EVP_DigestUpdate(&c,输入,strlen(输入));
执行副总裁(首席执行官、总经理和总经理);
执行副总裁MD CTX清洁(c);
返回md;
}
无符号字符*符号(EVP_PKEY*键,无符号字符*数据)
{
执行副总裁MD CTX c;
无符号字符*sig;
无符号整数len;
执行副总裁MD CTX初始(&c);
sig=malloc(执行副总裁尺寸(关键尺寸));
EVP_信号装置(&c,类型);
EVP_SignUpdate(&c,数据,strlen((char*)数据));
执行副总裁签署最终文件(&c、sig和len、key);
执行副总裁MD CTX清洁(c);
返回信号;
}
int验证(EVP_PKEY*密钥、无符号字符*数据、无符号字符*原始)
{
执行副总裁MD CTX c;
int ret;
执行副总裁MD CTX初始(&c);
EVP_VerifyInit(&c,类型);
EVP_VerifyUpdate(&c,数据,(无符号整数)sizeof(数据));
ret=EVP_VerifyFinal(&c,原件,(无符号整数)strlen((字符*)原件),密钥);
返回ret;
}
内部主(空)
{
执行副总裁*sk,*pk;
文件*sfd,*pfd;
无符号字符*hash,*sig;
无符号整数i;
sfd=fopen(“secret.pem”,“r”);
pfd=fopen(“public.pem”,“r”);
sk=PEM_read_PrivateKey(sfd,NULL,NULL,NULL);
pk=PEM_read_PUBKEY(pfd,NULL,NULL,NULL);
fclose(sfd);
fclose(pfd);
OpenSSL_添加_所有_摘要();
类型=EVP_get_digestbyname(“SHA1”);
散列=sha(“moo”);
对于(i=0;i
您传递的尺寸不正确:

EVP_VerifyUpdate(&c, data, (unsigned int)sizeof(data));
由于
data
定义为
无符号字符*
sizeof(data)
可能是4或8(保存指针所需的字节数)

尝试传递已分配的实际字节数,即
EVP\u PKEY\u size(key)
。您必须将其传递给
verify()
函数


可能还有其他问题,但这个问题引起了我的注意。

我知道这是一个老问题,但一个错误可能会让用户感到困惑

在验证功能中,应交换原始数据和数据,将原始数据交换给EVP_VerifyUpdate,并将数据交换给EVP_VerifyFinal。不应使用字符串长度,因为字节数组可以包含0x00作为有效值,该值将被识别为“\0”