OpenSSL RSA签名验证:哈希和填充?

ste*_*eha 5 c openssl rsa libtomcrypt

我正在尝试编写代码来验证一些RSA签名.签名是使用OpenSSL命令行工具制作的,使用此命令行的等效命令:

openssl dgst -sha1 -sign private_key_file.pem < binary_data_file > sig
Run Code Online (Sandbox Code Playgroud)

我想用来libtomcrypt做验证:

http://www.libtom.org/

以下是RSA验证函数的调用签名libtomcrypt:

int rsa_verify_hash_ex(
    const unsigned char *sig, unsigned long siglen,  // signature to verify
    const unsigned char *hash, unsigned long hashlen,  // hash value to check against sig
    int padding,  // defined constant value, see below
    int hash_idx,  // identifies which hash algorithm, see below
    unsigned long saltlen,  // specify salt length, see below
    int *stat,  // output parameter, returns whether verify succeeded or not
    rsa_key *key);  // RSA public key to use for verify
Run Code Online (Sandbox Code Playgroud)

如果该操作没有错误,则返回0,否则返回错误代码.如果它无错误地运行,则stat输出参数指示是否验证了签名.

大多数参数看起来很简单:传入签名以进行检查,用于比较它的哈希值以及用于检查的RSA密钥. hash_idx从包含的示例代码中可以清楚地看出libtomcrypt; 它是支持的哈希算法表的索引,我可以找到与此代码段一起使用的正确值:hash_idx = find_hash("sha1")

但我想知道这些paddingsaltlen价值观. padding不要太担心我,因为只有两个可能的值,我可以尝试两者.但是我应该通过saltlen什么?

用于RSA验证的OpenSSL函数的OpenSSL文档不显示saltlen参数.openssl dgst(即结果man dgst)的手册页不讨论盐.

所以我的问题:

  • 如何确定要使用的正确盐长?
  • OpenSSL的dgst命令是否在输入中插入任何额外的内容,例如:(stdin)=

(我(stdin)=通过搜索StackOverflow 找到了这个东西:为什么我用OpenSSL和Java生成的RSA-SHA256签名不同?)

  • libtomcrypt还有一个被称为pkcs_1_pss_decode()"解码PSS编码的签名块" 的函数.这是我需要打电话的功能吗?

感谢你给与我的帮助.

编辑:感谢下面的帮助,来自@Jonathan Ben-Avraham,我今天能够正常工作.我的问题的答案分别是:

  • 盐的长度为0,根本不含盐.
  • 不,OpenSSL没有插入任何额外的东西,如 (stdin)=
  • 我需要打电话rsa_verify_hash_ex(),我需要将padding参数指定为LTC_LTC_PKCS_1_V1_5.

Jon*_*ham 8

没盐:

首先,生成数据的二进制SHA1哈希值:

openssl dgst -sha1 -binary -out hash1 some_data_file
Run Code Online (Sandbox Code Playgroud)

这是SHA1哈希或摘要.文件中没有预先添加的盐some_data_file.它openssl dgst -sha1本身不添加盐.请注意,输出文件只是一个20字节的SHA1哈希,没有盐.如果有salt,则哈希必须包含它,可能在保存SHA1哈希的最后20个字节之前加上.

接下来,hash1使用您的私钥对SHA1哈希文件进行签名:

openssl pkeyutl -sign -in hash1 -inkey privkey.pem -pkeyopt digest:sha1 -out sig1
Run Code Online (Sandbox Code Playgroud)

现在注册的some_data_fileopenssl dgst:

openssl dgst -sha1 -sign privkey.pem < some_data_file > sig2
Run Code Online (Sandbox Code Playgroud)

最后,比较两个签名:

diff sig1 sig2
Run Code Online (Sandbox Code Playgroud)

你应该看到它们是一样的.这告诉我们,对没有salt的文件的原始SHA1哈希进行签名与使用该openssl dgst -sha1 -sign命令对文件进行签名是相同的,因此openssl dgst -sha1 -sign在生成其SHA1哈希时,该命令也必须不使用任何salt sig2.

另请注意,使用弃用时无法获得相同的结果rsautl:

openssl rsautl -sign -in hash1 -inkey privkey.pem -out sig1
Run Code Online (Sandbox Code Playgroud)

而不是openssl pkeyutl,显然是因为openssl rsautl -sign包括输出中的加密文本以及签名.有关详细信息,请参阅此SE帖子