OpenSSL C ++ RSA标志与命令行标志不同

Ale*_*lis 5 c++ openssl rsa sign digital-signature

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

openssl genrsa -out key.pem 1024
Run Code Online (Sandbox Code Playgroud)

现在我有了我的私钥。然后这就是我登录命令行的方式:

echo "hola" | openssl rsautl -pkcs -sign -inkey key.pem > sign.txt
Run Code Online (Sandbox Code Playgroud)

至此,所有工作似乎都正常了,现在我在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);
}
Run Code Online (Sandbox Code Playgroud)

当我调用initRSA()时,它会打印生成的签名。但是与命令行生成的签名不同。

因为不能确定sizeof是否采用“文本”的真实长度,所以我尝试使用length = 4(hola有4个字符)和5(可能计算\ 0),结果不是预期的。

我在密码学方面的知识非常有限。不知道问题出在哪里。

kcr*_*gie 5

显然是因为您使用了错误的命令行。您需要以下命令行,该命令行可计算输入摘要并使用私钥对其进行签名:

echo -n "hola" | openssl dgst -sha1 -binary -sign key.pem >sign.txt
Run Code Online (Sandbox Code Playgroud)

使用pkeyutl还会执行其他一些额外的操作,如下所述:使用C例程和openssl dgst,rsautl命令时的不同签名

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