来源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函数导致签名无效。散列->数据的输入是来自"你好SHA-256"的SHA-256的a7cd893b31b0ea44ed1aa7cafcda58744cc5a02ef26feccceaae9a8becb83a0散列。数据->len是64。然后,代码执行从十六进制到二进制的转换。然后我将这些信息传递给PK11_Sign。我有没有踩错台阶?
Q2(散列的BER编码是什么意思?如果我们有一个十六进制的散列字符串,那么我们将其转换为散列的二进制值,这就是BER?或者这句话的意思是,它只支持DER?
Q3(PK11_Sign的任何样本是否与上述操作类似?
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:
- 对于附录B.1中提到的六个散列函数,DERDigestInfo值的编码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.
请注意,如果您做的每件事都正确,那么您应该能够在运行时将每件事直接视为二进制;应该不需要先将散列的输出编码为二进制,然后再返回。
我无法回答Q1,因为我不熟悉NSS API,但我认为Q2很容易回答。
当您按照PKCS#1(RFC3447(中定义的RSASSA-PKS1-v1_5签名方案创建签名时,您需要首先计算哈希值并将其放入DigestInfo结构中:
DigestInfo ::= SEQUENCE {
digestAlgorithm AlgorithmIdentifier,
digest OCTET STRING
}
然后,DigestInfo需要进行BER编码,并使用私钥进行加密。因此,您不仅要加密原始哈希值,还要加密BER编码的DigestInfo结构,该结构包含原始哈希值和哈希算法OID。