PK11_Sign带填充

时间:2015-07-04 03:49:29

标签: hash cryptography mozilla pkcs#11 nss

来自http://www-archive.mozilla.org/projects/security/pki/nss/tech-notes/tn7.html,它声明

  

对于低级别签名,请使用PK11_Sign()。这两个功能都有   PKCS#1包装数据。 PK11_Sign不执行BER   散列的编码(在SGN_函数中完成)

来自代码API

/*
 * sign a hash. The algorithm is determined by the key.
 */
SECStatus
PK11_Sign(SECKEYPrivateKey *key, SECItem *sig, const SECItem *hash)

Q1)我的PK11_Sign功能导致签名无效。 hash->数据的输入是来自" Hello SHA-256"的SHA-256的哈希值.7cm。 data-> len是64.然后,代码执行十六进制到二进制。然后我将这些信息传递给PK11_Sign。我错过了任何步骤吗?

Q2)哈希的BER编码是什么意思?如果我们在hexdecimel中有一个hash字符串,那么我们将它转​​换为hash的二进制,即BER?或者句子意味着,它只支持DER?

Q3)PK11_Sign的任何样本与上述操作类似吗?

2 个答案:

答案 0 :(得分:1)

Q1:是的,您需要使用SHA-256的OID的ASN.1 / DER编码加上哈希值本身的标记和长度来预先添加哈希值。

Q2:BER是ASN.1的基本编码规则,它是根据ASN.1定义构造的数据的二进制Tag-Length-Value(TLV)编码。 DER是BER的规范子集。你绝对应该在这里使用DER。

第三季:嗯,不,但我认为我可以为你加速,因为创建甚至了解ASN.1是相当费时的。由于OID(散列算法的标识符)和散列的长度保持静态,因此DER编码也是静态的。因此,您可以将以下十六进制前缀添加到您选择的哈希值中。

RSA PKCS#1 2.1(和2.2)第9.2节注释1:

  
      
  1. 对于附录B.1中提到的六个散列函数,DER     DigestInfo值的编码T等于以下内容:
  2.   
  MD2:     (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 02 05 00 04
               10 || H.
  MD5:     (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04
               10 || H.
  SHA-1:   (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H.
  SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00
               04 20 || H.
  SHA-384: (0x)30 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00
               04 30 || H.
  SHA-512: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00
                  04 40 || H.

请注意,如果您正确地执行了所有操作,那么您应该能够在运行时直接将所有内容视为二进制文件;不应该首先将哈希的输出编码为二进制,然后再重新编码。

答案 1 :(得分:0)

由于我不熟悉NSS API,我无法回答Q1,但我认为Q2很容易回答。

根据PKCS#1(RFC3447)中定义的RSASSA-PKCS1-v1_5签名方案创建签名后,您需要先计算哈希值并将其放入DigestInfo结构中:

DigestInfo ::= SEQUENCE {
    digestAlgorithm AlgorithmIdentifier,
    digest OCTET STRING
}
然后需要对DigestInfo进行BER编码并使用私钥加密。因此,您不是仅加密原始哈希值,而是加密BER编码的DigestInfo结构,其中包含原始哈希值以及哈希算法OID。