使用pkcs#11 api使用RSA签署sha256哈希?

Cha*_*cat 5 rsa pkcs#11

我目前正在使用pyPkcs11来签名文件.

以下调用适用于使用RSA和sha256对公共文件进行签名,

session.sign(privKey, toSign, Mechanism(CKM_SHA256_RSA_PKCS, None)
Run Code Online (Sandbox Code Playgroud)

但是我的一些文件已经被散列(sha256),并且签名需要提供与此openSSL命令相同的输出:

openssl pkeyutl -sign -pkeyopt digest:sha256 -in <inFilePath> -inkey <keyPath> -out <outFilePath>
Run Code Online (Sandbox Code Playgroud)

我尝试了以下调用,它在签名之前不会生成文件的哈希值,

session.sign(privKey, toSign, Mechanism(CKM_RSA_PKCS, None)
Run Code Online (Sandbox Code Playgroud)

但结果不是我预期的结果,并且根据PKCS#11中这篇文章CKM_RSA_PKCS与CKM_RSA_X_509机制的第一个答案,

另一方面,CKM_RSA_PKCS也执行PKCS#1标准中定义的填充.此填充在EMSA-PKCS1-v1_5中定义,步骤3,4和5.这意味着此机制应仅接受比模数大小短11个字节的消息.要创建有效的RSASSA-PKCS1-v1_5签名,您需要自己执行EMSA-PKCS1-v1_5的步骤1和2.

经过一些研究后,我的文件似乎包含了RFC 3447描述的签名的第一步,因此缺少的部分是第二步,其中生成了ASN.1值.

我可以用pkcs11强制执行此操作吗?

PKCS#11文件似乎不包含任何有关它的信息.

fgr*_*ieu 8

我看到有两种方法可以做到这一点; 适当的一个取决于令牌(并非所有令牌/包装器都执行所有机制).

  • 正如在另一个答案中所解释的那样,你可以将你开始的32字节SHA-256装饰成一个完整的填充消息代表.基本上,在说明的PKCS#1,如果RSA密钥是ķ八位组(与我假定ķ ≥51+ 11 = 62个八比特组,即一个公共模数至少8⋅62-7= 489个比特,这是必须的安全),你

    1. 在左边附加19个八位字节的字符串
      30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20
      产生一个51个八位字节的字符串,它实际上是哈希类型和值的ASN.1 DER编码
      DigestInfo ::= SEQUENCE {
          digestAlgorithm DigestAlgorithm,
          digest OCTET STRING
      }
      
    2. 在左边还附加一串k -51八位字节(其中k -51-3是FF)
      00 01 FF FF FF FF..FF FF FF FF 00
      产生一个k -octet字符串
    3. 使用机制CKM_RSA_X_509(长度为k个八位字节)进行签名.
  • 或者,或者:按[1.]执行; 跳过[2.]; 并在[3.]中使用机制CKM_RSA_PKCS(长度为51个八位字节).

免责声明:我没有检查,最近没有使用过PKCS#11设备.

注意:虽然没有针对其正确实现的已知攻击,但使用PKCS#1 v1.5签名填充越来越不满意了; 例如法国当局推荐

RecomSignAsym-1.Ilestcomndmandéd'diversdesmécanismesdesignatureasymétriquedisposdd'une preuvedesécurité.

或者,用英语:

建议使用具有安全性证明的非对称签名机制

他们提到了RSA-SSA-PSS(原文如此).作为奖励,PKCS#11实现的机制是CKM_RSA_PKCS_PSS,它接受一个哈希,而不是要签名的数据,这使得所要求的是微不足道的.