来自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的任何样本与上述操作类似吗?
答案 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:
- 对于附录B.1中提到的六个散列函数,DER DigestInfo值的编码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.
请注意,如果您正确地执行了所有操作,那么您应该能够在运行时直接将所有内容视为二进制文件;不应该首先将哈希的输出编码为二进制,然后再重新编码。
答案 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。