1

我不确定我是否应该在这里或在 Security Stackexchange 中问这个问题。

无论如何,我最近在使用 TPM 处理 RSA 签名时遇到了一个问题,我将填充方案从 RSASSA-PKCS1-v1_5 切换到 RSASSA-PSS。我认为这应该没什么区别,但我注意到 TSS.MSR(.NET TPM 库)中的一个示例不再起作用。我在https://github.com/microsoft/TSS.MSR/issues/109开始了一个关于它的问题。

但我想检查一下,如果有人可以分享意见,是否需要做或注意一些明显的事情,而不是改变填充方案?

我认为不是,这也隐含在 .NET RSA 库等参数中,例如https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rsasignaturepadding以及如何使用它喜欢

using(var rsaKey = RSA.Create(keySizeInBits: 2048))
{
   byte[] message = /* Random data. */
   var sig = rsaKey.SignData(message, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
}

我从https://security.stackexchange.com/questions/183179/what-is-rsa-oaep-rsa-pss-in-simple-termshttps://crypto.stackexchange.com/questions/77881中的问题中看到/are-rsa-pss-parameters-standardized在其他地方,填充的实际发生方式更为复杂。但假设它是库的一个实现细节,并且签名检查似乎不匹配或不起作用,一个结论是可能需要检查此 TSS.NET 库中的各种内部参数,例如填充。所以,因此我想确保自己这个结论是正确的,并且可能没有非常明显的东西。举个例子:不要使用 SHA-256 或明确地将盐大小精确地设置为 nn (好的,这可能是一个通常不应该关心的实现细节)。

附录:

这是在接受Maarten Bodewes的优秀笔记后写的。

将散列从 SHA-256 切换到 SHA-1 并没有消除链接示例中验证签名的失败。不过,正如预期的那样,“nameSize”或摘要更改为 20 个字节。因此,如果在示例或某处的库中没有正确处理一些“挥之不去的默认值”,则仅此一项(可能是部分解决方案)并不是切换到 RSASSA-PSS 填充方案失败的原因。

探索仍在继续。:)

4

1 回答 1

2

其实padding是有一些配置选项的,使用该功能时需要提前设置。

奇怪的是,标准中没有针对 PSS 功能描述这些“选项”。但是,它们针对 PSS 填充机制列出的:

Options:

  Hash     hash function (hLen denotes the length in octets of the hash
           function output)
  MGF      mask generation function
  sLen     intended length in octets of the salt

但是,这仍然不能完全配置 PSS,因为 MGF 本身就是一种算法,并且该算法也有参数。

因此,最好查看参数的 ASN.1 结构以获得一个好主意:

RSASSA-PSS-params ::= SEQUENCE {
   hashAlgorithm      [0] HashAlgorithm      DEFAULT sha1,
   maskGenAlgorithm   [1] MaskGenAlgorithm   DEFAULT mgf1SHA1,
   saltLength         [2] INTEGER            DEFAULT 20,
   trailerField       [3] TrailerField       DEFAULT trailerFieldBC
}

幸运的是只有一个掩码生成函数:MGF1。也只指定了一个尾部字段:trailerFieldBC,所以这主要是为将来的更改指定的。

如您所见,其中有两个散列函数,一个用于消息/输入数据本身,另一个用于掩码生成函数 (MGF)。所以哈希反过来是 MGF1 的配置参数。该标准表明最好对消息散列和 MGF1 散列使用相同的散列函数。但是,算法可能会使用默认值,如您在结构中看到的 SHA-1。AFAIK,Java 始终对 MGF1 使用 SHA-1,但 .NET 使用与消息哈希相同的哈希。

类似地,盐长度通常设置为hLen,即散列的输出大小。它默认为 20,但那是因为这是 SHA-1 的输出大小。零值也是一种选择,但我认为一般留到 20。

所以是的,不幸的是,您确实需要检查是否使用了相同的参数。一个好的库应该清楚地指定使用什么,或者至少可以选择明确地配置它们。但是,如果这是一个好的库的要求,那么存在许多不好的库。此外,您绝对不应该尝试从签名本身获取此类信息或在验证过程中猜测多个算法,因为这会将安全性降低到可能的最不安全的算法。

最后,当您找到安全且兼容的 PSS 方案时,我建议您在代码中明确指定使用哪组参数。这可以使用显式参数来完成(即使默认值用于特定库)。如果前者不可能,您也可以在评论中指出参数。单独记录您的计划并在评论中指出它不会有什么坏处。

于 2021-07-08T12:23:15.617 回答