c - openssl 没有正确验证签名

标签 c openssl rsa

根据 OpenSSL 文档,我/认为/我所做的是正确的..但显然不是。编译文件(使用 gcc -g -Wall -Wextra -lssl sign.c)不会产生任何错误或警告。 EVP_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;
}

最佳答案

您传递的尺寸不正确:

EVP_VerifyUpdate(&c, data, (unsigned int)sizeof(data));

由于 data 被定义为 unsigned char *sizeof(data) 可能是 4 或 8(保存一个字符所需的字节数)指针)。

尝试传递您分配的实际字节数,即 EVP_PKEY_size(key)。您必须将其传递给您的 verify() 函数。

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

关于c - openssl 没有正确验证签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9380402/

相关文章:

Ubuntu 上的 strdup() 崩溃

c++ - 在 C 和 C++ 中都有效的代码在用每种语言编译时会产生不同的行为吗?

java - 非对称加密差异 - Android 与 Java

ubuntu - stream_get_contents():SSL 操作失败,代码为 1。OpenSSL 错误消息:错误:0A000126:SSL 例程::读取时出现意外 eof

C# 使用 RSA 加密 PHP 解密

java - BouncycaSTLe:如何创建 RSA 私钥的加密 PKCS8 表示?

c - 在没有字符串库的情况下从 C 中的文件读取字符串时出现问题

c - 将 GNU 科学库与 Code::Blocks 一起使用时出错

security - 如何使用 openssl *以最小的功率* 创建 CA

php - API原因 "Curl error: OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 10054"