1

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->data 的输入是 SHA-256 的 a7cd893b31b0ea44ed1aa7cafcda658744cc5a02ef26feccceaae9a8becb83a0 哈希,来自“Hello SHA-256”。data->len 是 64。然后,代码执行十六进制到二进制。然后我将这些信息传递给 PK11_Sign。我错过了任何步骤吗?

Q2)哈希的BER编码是什么意思?如果我们有一个十六进制的哈希字符串,那么我们将它转​​换为哈希的二进制,即BER?或者这句话的意思是,它只支持DER?

Q3) PK11_Sign 是否有类似上述操作的样本?

4

2 回答 2

1

Q1:是的,您需要在哈希值前面加上 SHA-256 的 OID 的 ASN.1 / DER 编码加上哈希值本身的标签和长度。

Q2:BER 是 ASN.1 的基本编码规则,它是根据 ASN.1 定义结构化的数据的二进制标记长度值 (TLV) 编码。DER 是BER的规范子集。您绝对应该在这里使用 DER。

Q3:嗯,不,但我想我可以为你加快速度,因为创建甚至学习 ASN.1 是相当耗时的。由于 OID(哈希算法的标识符)和哈希长度保持不变,DER 编码也是静态的。因此,您只需将以下十六进制前缀添加到您选择的哈希中。


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

  1. 对于附录 B.1 中提到的六个哈希函数,DigestInfo 值的 DER 编码 T 等于以下:
  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.

请注意,如果您正确执行所有操作,那么您应该能够在运行时将所有内容直接视为二进制;不需要先将散列的输出编码为二进制,然后再返回。

于 2015-07-04T07:54:38.783 回答
0

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

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

DigestInfo ::= SEQUENCE {
    digestAlgorithm AlgorithmIdentifier,
    digest OCTET STRING
}

DigestInfo 然后需要使用私钥进行 BER 编码和加密。因此,您不仅要加密原始散列值,还要加密包含原始散列值和散列算法 OID 的 BER 编码的 DigestInfo 结构。

于 2015-07-04T06:08:48.183 回答