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

时间:2017-11-03 15:43:53

标签: rsa pkcs#11

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

以下调用适用于使用RSA和sha256

对公共文件进行签名
session.sign(privKey, toSign, Mechanism(CKM_SHA256_RSA_PKCS, None)

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

openssl pkeyutl -sign -pkeyopt digest:sha256 -in <inFilePath> -inkey <keyPath> -out <outFilePath>

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

session.sign(privKey, toSign, Mechanism(CKM_RSA_PKCS, None)

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

  另一方面,

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

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

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

PKCS#11 documentation似乎不包含任何有关它的信息。

2 个答案:

答案 0 :(得分:7)

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

  • 正如本other answer中所述,您可以将您开始的32位八位字节SHA-256装饰成一个完整的填充消息代表。基本上,如PKCS#1中所述,如果RSA密钥是 k 八位字节(我假设 k ≥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签名填充越来越不满意了;例如French authorities recommend

  

RecomSignAsym-1。 Ilestcomndmandéd'considedesmécanismesdesignatureasymétriquedisposdd'une preuvedesécurité。

或者,用英语:

  

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

他们提到了RSA-SSA-PSS( sic )。作为奖励,PKCS#11实现的机制是 CKM_RSA_PKCS_PSS ,它接受哈希,而不是要签名的数据,这使得所要求的内容变得微不足道。

答案 1 :(得分:2)

我担心,没有PKCS#11功能,它可以做你想要的。

我所知道的唯一解决方案是,手动将PKCS#1 v1.5填充应用于哈希,然后使用 CKM_RSA_X_509 (原始或教科书RSA)机制对块进行签名