'dgst verify and sign' 相当于 'RSA_Verify()'

'dgst verify and sign' equivalent with 'RSA_Verify()'

我正在使用 RSA_verify() 函数来验证我使用 openssl 程序(通过控制台)签署的 SHA。 RSA_verify() 总是返回一个不成功的验证,所以我认为我向它发送了不正确的参数。

以下控制台命令是 运行 in Linux Ubuntu with OpenSSL 0.9.8k.

据我所知,C 函数是为 Android 编译的,使用 OpenSSL 1.0.1...c。它肯定是 1.0.1(我们正在更新它以避免 Heartbleed 问题)。

这就是我做的...由于我是自学的,所以请原谅我的错误。

  1. 生成私钥

    openssl genrsa -out private.key 2048
    
  2. 从私钥中提取public密钥

    openssl rsa -in private.key -out public.key -outform PEM -pubout
    
  3. 从名为 permissions 的文件计算 SHA,然后使用 private.key 对其进行签名,输出将是 SHA 但使用 RSA 加密 (permissions.sign)

    openssl dgst -sha256 -sign private.key -out permissions.sign permissions
    
  4. 根据权限文件验证收到的 SHA 签名(在 Ubuntu 控制台中成功)

    openssl dgst -sha256 -verify public.key -signature permissions.sign permissions
    
  5. 我复制权限文件,permissions.sign文件和public.key文件到Android.

    [=83中的文件系统=]
  6. 我确认 permissions.sign 是使用权限和匹配的 private.key 创建的...所有这些都与我的 public.key (我没有Android).

  7. 中的私钥

这是 C 函数。

#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>

...

/* Initialize the public key */
RSA *pub_key = RSA_new();

if(NULL == pub_key)
{
   ANDROID_LOGE("RSA_new failed");
   result = 0;
}
else
{
   FILE* fp = fopen(public_key, "r");

   if(NULL == fp)
   {
      ANDROID_LOGE_P("fopen [%s] failed", public_key);
      result = 0;
   }
   else
   {
      /* Read it from the passed path */
      if(PEM_read_RSA_PUBKEY(fp, &pub_key, NULL, NULL) == NULL)
      {
         ANDROID_LOGE_P("[%s] can't be read", public_key);
         result = 0;
         fclose(fp);
      }
      else
      {
         /* Verify the file and its SHA with the public key */
         int verified = RSA_verify(
             NID_sha256,
             file, /* message digest (message to validate) */
             file_size, /* message size */
             sign, /* signature (signed SHA) */
             sign_size, /* signature size */
             pub_key);
         ANDROID_LOGD("NID_sha256");

         if(verified)
         {
            result = 1;
            ANDROID_LOGD_P("[%s] is valid", file_to_verify);
         }
         else
         {
            ANDROID_LOGE_P("[%s] is NOT valid", file_to_verify);
         }

         fclose(fp);
      }

      RSA_free(pub_key);
   }
}

那么问题是:

我在签名过程中使用的命令是否等同于我在验证过程中使用的 C 函数?

如果需要更多信息或我可以在哪里研究更多信息,请告诉我。

谢谢!

编辑:我在调用 RSA_Verify():

后添加了一些错误打印

ANDROID_LOGE_P("openssl: %s", ERR_reason_error_string(ERR_get_error()));

它打印:

openssl:签名错误

仍在调查中。

在我阅读 public 键的过程中缺少几个步骤。

生成私钥和public密钥的正确命令如下:

生成私钥 "openssl genrsa -out private.key 2048"

从私钥中提取public密钥(DER证书形式)(RSA_SHA_Verify()需要) "openssl req -outform DER -new -x509 -key private.key -out public.key -days 30000"

生成没有证书信息的 public 密钥(只有 "openssl dgst -sha1 -verify ..." 需要) "openssl x509 -inform DER -in public.key -pubkey -noout > public_no_cert.key"

使用私钥签署文件 "openssl dgst -sha1 -sign private.key -out permissions.sign permissions"

使用 public 密钥验证文件(无证书信息) "openssl dgst -sha1 -verify public_no_cert.key -signature permissions.sign permissions"

详情请参考OpenSSL.org上的文档。我需要一个持有 public 密钥的 X509 DER 证书来验证带有 RSA_verify() 的签名 SHA。

在命令模式下与 RSA_verify() 的等效项是:

openssl dgst -sha1 -verify public.key -signature permissions.sign permissions

代码源请参考这个link: http://www.bmt-online.org/geekisms/RSA_verify

乍一看无法编译,您必须对其进行调整。调用里面的函数如下:

   result = sign_data(
         input_file_buffer,
         input_file_size,
         private_key_buffer,
         private_key_size,
         (void**)&signature,
         &signature_size);

   result = verify_data(
         input_file_buffer,
         input_file_size,
         signature_buffer,
         signature_size,
         public_key_buffer,
         public_key_size);

一切都必须在 RAM 中,将它们作为指针传递。

签名函数期望指向指针 (**) 的指针将已签名的 SHA 保存到其中。您可以稍后将其保存到文件中。

在 Ubuntu openssl 0.9.8k 下测试。

如果您发现缺少某些内容,请告诉我。感谢阅读!

编辑:这是源代码的 link... http://migsantiago.com/index.php/tutoriales/32-firma-y-valida-archivos-con-openssl