C# - как вычислить ASN.1 DER кодирование конкретного хэш-алгоритма?

учитывая хэш-алгоритм, такой как SHA1 или SHA256, как бы я пошел о получении ASN.1 кодировка DER для него, как определено в RFC3447? (см. стр. 42 - ссылке) Ниже приведен желаемый результат.

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 Der процедура преобразования (или hardcode их). Есть идеи?

1 ответов


это поможет вам часть пути:

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 PKCS#1 v1.5 подпись, вам было бы лучше просто использовать RSAPKCS1SignatureFormatter.


EDIT: еще несколько деталей:

в АСН.1 вы хотите закодировать это:

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

здесь

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

Итак, чтобы начать с внутри: digest-AlgorithmIdentifier состоит из SEQUENCE-tag (30), длина (мы вернемся к этому), OID и некоторые параметры. OID для f.X. SHA-1-это 1.3.14.3.2.26, который кодируется как 06 05 2b 0e 03 02 1a (OID-tag 06, длина 5 и кодировка OID). Все обычные хэш-функции имеют NULL в качестве параметров, который кодируется как 05 00. Таким образом, AlgorithmIdentifier содержит 9 байтов - это выше.

теперь мы можем продолжить с остальной частью DigestInfo: строка октета, который содержит значение хэша. 20 байт хэша SHA-1 будут закодированы как 04 20 <HASH>.

длина содержимого DigestInfo теперь составляет 11+22 байта (). Нам нужно запустить DigestInfo с помощью SEQUENCE-tag, поэтому мы заканчиваем: 30 21 30 09 06 05 2b 0w 02 01 1a 05 00 04 20 <HASH>.

Если вам нужно сгенерировать его самостоятельно, теперь вы сможете увидеть, что length2 = encodedOid.Длина + 2 и что длина = измерения-2+ 2 + 2 + hashlength.

Если вам нужна дополнительная информация о кодирования ASN.1, я могу порекомендовать Burt Kaliski руководство непрофессионала к подмножеству ASN.1, BER и DER.