2017-11-03 251 views
3

我目前使用pyPkcs11来签署文件。使用pkcs#11 api签名sha256 hash with RSA?

以下调用适用于签署与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步和第2步。

经过一番研究,看来我的文件中包含了RFC 3447描述签名的第一步,因此丢失的部分是第二个,其中产生的ASN.1值。

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

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

回答

5

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

  • 在本other answer解释,你可以装饰的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.1DER编码每
       
      DigestInfo ::= SEQUENCE { 
          digestAlgorithm DigestAlgorithm, 
          digest OCTET STRING 
      } 
      
      哈希类型和值
    2. 进一步追加上的ķ -51个八位字节(其ķ -51-3是FF
      00 01 FF FF FF FF..FF FF FF FF 00
      产生一个ķ一字节串
    3. 注册与机构CKM_RSA_X_509左边字符串(长度k八比特组)。
  • 或者,或者:如[1.]中的执行;跳过[2.];和[3.]使用机制CKM_RSA_PKCS(长度51个八比特组)。

声明:我没有检查,最近也没有使用过PKCS#11设备。

注意:尽管没有已知的攻击来正确执行它,但PKCS#1 v1.5签名填充的使用越来越多地被皱起了眉头;例如French authorities recommend

RecomSignAsym-1。   Il estrecommandéd'employer desmécanismesde signatureasymétriquedisposant d'une preuve desécurité。

(建议使用具有安全证明的非对称签名机制)。他们提到RSA-SSA-PSS(sic)。作为奖励,PKCS#11的实现是机制CKM_RSA_PKCS_PSS它接受一个散列,而不是要签名的数据,使得所要求的事情变得微不足道。

+0

谢谢,我会尽快做到这一点。 对于注意,因为文件和签名机制不是实习生的选择,但决定我的客户,我没有控制他们 –

2

恐怕没有PKCS#11功能,它可以做你想做的。

我所知道的是唯一的解决办法,手动应用PKCS#1 v1.5的填充到您的哈希值,然后使用CKM_RSA_X_509(生或教科书RSA)机制签署块。

+0

谢谢,我担心这将是唯一的解决方案 –