代码之家  ›  专栏  ›  技术社区  ›  Taylor Leese

C-如何计算特定哈希算法的asn.1 der编码?

  •  8
  • Taylor Leese  · 技术社区  · 14 年前

    给定一个类似于sha1或sha256的哈希算法,我该如何获得在rfc3447中定义的ASN.1 der编码呢?(见第42页- link )下面是所需的输出。

    MD5        30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04 10
    SHA-1      30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14
    SHA-256    30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20
    SHA-384    30 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00 04 30
    SHA-512    30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40
    

    我希望有一种聪明的方法可以在C中实现这一点,不需要我编写一个从OID到ASN.1的转换例程(或者对它们进行硬编码)。有什么想法吗?

    1 回复  |  直到 14 年前
        1
  •  15
  •   Rasmus Faber    14 年前

    这将使您成为其中一员:

    string oidString = CryptoConfig.MapNameToOID(hashName); // f.x. "MD5"
    byte[] encodedOid = CryptoConfig.EncodeOID(oidString); // Gives you f.x. 06 08 2a 86 48 86 f7 0d 02 05
    

    然后您只需要将它插入序列标题中( 30<length>30<length2><oid>050004<hashlength> )

    当然,如果您想创建一个RSA PKC 1 v1.5签名,最好只使用 RSAPKCS1SignatureFormatter .


    编辑: 更多细节:

    您要编码的ASN.1是:

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

    在哪里?

    AlgorithmIdentifier  ::=  SEQUENCE  {
          algorithm               OBJECT IDENTIFIER,
          parameters              ANY DEFINED BY algorithm OPTIONAL  
    }
    

    所以从内部开始:摘要算法标识符由 SEQUENCE -标签(30),一个长度(我们将回到这个),一个OID和一些参数。f.x.sha-1的OID是1.3.14.3.2.26,编码为 06 05 2b 0e 03 02 1a (OID标签06,长度5和OID的编码)。所有常见的哈希函数的参数都为空,其编码为 05 00 . 所以算法标识符包含9个字节——这就是上面所说的。

    现在我们可以继续使用digestinfo的其余部分:包含哈希值的八进制字符串。sha-1的20字节哈希将编码为 04 20 <HASH> .

    DigestInfo内容的长度现在为11+22字节()。我们需要用 顺序 -标记,这样我们最终得到: 30 21 30 09 06 05 2b 0w 02 01 1a 05 00 04 20 <HASH> .

    如果您需要自己生成它,现在应该能够看到length2=encodedoid.length+2和length2+2+2+hashlength。

    如果您需要更多有关编码ASN.1的信息,我可以推荐Burt Kaliski的 A Layman's Guide to a Subset of ASN.1, BER, and DER .