OpenSSL C++ RSA签名与命令行签名不同

5

我正在尝试在C++中签名文本,然后在命令行中进行验证。我正在使用OpenSSL库。这是我的密钥生成命令行:

openssl genrsa -out key.pem 1024

现在我有了私钥。接下来我将通过命令行完成登录的签名过程:
echo "hola" | openssl rsautl -pkcs -sign -inkey key.pem > sign.txt

目前一切似乎都正常,现在我有一个在sign.txt中的签名。 现在我试图用C语言做同样的事情... 这是我的代码:

RSA * rsaPrivKey;


RSA * createRSAWithFilename (const char * filename, int publicKey)
{
   FILE * fp = fopen (filename, "rb");

   if (fp == NULL)
   {
      printf ("Unable to open file %s \n", filename);
      return NULL;
   }
   RSA *rsa = RSA_new ();

   if (publicKey)
      rsa = PEM_read_RSA_PUBKEY (fp, &rsa, NULL, NULL);
   else
      rsa = PEM_read_RSAPrivateKey (fp, &rsa, NULL, NULL);

   return rsa;
}


void initRSA (void)
{
   rsaPrivKey = createRSAWithFilename ("key.pem", 0);

   unsigned char text[] = {"hola"};
   unsigned char encrypted[4098] = {};
   unsigned int outlen;

   unsigned char hash[20];
   if (!SHA1 (text, sizeof(text), hash)){
      printf ("SHA1 failed\n");
      exit (0);
   }
   if (!RSA_sign (NID_sha1, hash, 20, encrypted, &outlen, rsaPrivKey)){
      printf ("RSA_sign failed\n");
      exit (0);
   }

   printf ("Result:\n");
   for (int a = 0; a < outlen; a++)
      printf ("%c", encrypted[a]);

   exit (1);
}

当我调用initRSA()时,它会打印生成的签名...但是...与在命令行中生成的签名不同。因为不确定sizeof是否获取了"text"的实际长度,所以我尝试使用length = 4(hola有4个字符)和5(可能计算\0),结果不是预期的。我的加密知识非常有限...不知道问题出在哪里。

请在您的代码中包含您正在使用的库(即 #include <lib> 部分)。 - diegoperini
在我所遇到的所有echo实现中,不知道你的操作系统是什么,echo "hola"并不等同于"hola",而是等同于"hola\n"。 - Arne Kjetil Andersen
同意Arne的观点。尝试使用echo -n "hola" ;) - Iansus
请参阅 OpenSSL 维基上的 EVP 签名和验证 - jww
1个回答

5
显然是因为你正在使用错误的命令行。您需要使用此命令行,该命令行计算输入的摘要并使用私钥进行签名:
echo -n "hola" | openssl dgst -sha1 -binary -sign key.pem >sign.txt

使用pkeyutl会执行额外的操作,如此处所述:在使用C例程和openssl dgst、rsautl命令时签名不同

因此,如果您使用我提供的命令行(使用echo -n避免添加换行符),并将您的代码更改为sizeof(text)-1以跳过空终止符,则应该获得相同的输出。


嗨,kcraigie,谢谢...那就是问题所在,现在一切都很好 :)...非常感谢,我非常沮丧。 - user5583316

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接