根据 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/