Как импортировать подпись DSA в формате ASN.1 с помощью BouncyCastle (C #) - PullRequest
5 голосов
/ 23 октября 2009

OpenSSL, как и большинство других реализаций DSA, выводит подписи в формате ASN.1. Таким образом, 40-байтовая подпись (два 20-байтовых целых числа) становится 46 байтами из-за заголовков структуры ASN.1. (Подробнее см. в этом сообщении на форуме .)

У меня такой вопрос, как справиться с этим форматом в C #? (или в другом месте, если на то пошло)

Я потратил некоторое время, пытаясь справиться с этим с помощью пакетов .NET System.Security.Crypto, но разочаровался ( действительно расстраивает, потому что у него явно есть внутренний код для разбора ASN.1, поскольку он может читать формат DER , но вы не можете его использовать - но я отвлекся ... )

Затем я начал работать с библиотекой BouncyCastle C #. Я могу получить его в Asn1Object, и, если я раскрываю его во время отладки, я вижу, что он содержит DerSequence с двумя целыми числами, но как мне вытащить их (предпочтительно в BigIntegers, чтобы я мог передать их DSA.VerifySignature?)

Пример кода:

Byte[] msgText = ReadFile("test_msg.txt");
Byte[] msgSigRaw = ReadFile("test_sig_1.bin");  // reads binary ASN.1 sig using FileStream
Asn1Object sigASN = Asn1Object.FromByteArray(msgSigRaw);  // parses into Asn1Object
...
X509Certificate implCert = ReadCertificate("pubcert_dsa.cer");  // cert in DER format
DsaSigner DSA = new DsaSigner();
DSA.Init(false, implCert.GetPublicKey());
...
BigInteger sigIntR, sigIntS;
... //TODO: how to get signature from sigASN into sigIntR, sigIntS?
Boolean validSig = DSA.VerifySignature(msgText, sigIntR, sigIntS);  // my goal

Ответы [ 2 ]

4 голосов
/ 02 декабря 2009

Взгляните на эту статью CodeProject: http://www.codeproject.com/KB/security/CryptoInteropSign.aspx

Содержит код для преобразования подписи DSA в формат P1363, ожидаемый в C #.

2 голосов
/ 02 февраля 2010

Пример кода для проверки подписи DSA в BouncyCastle C #:

ISigner sig = SignerUtilities.GetSigner("SHA1withDSA");
sig.Init(false, implCert.GetPublicKey());
sig.BlockUpdate(msgText, 0, msgText.Length);
bool valid = sig.VerifySignature(msgSigRaw);

Обратите внимание, что этот подписант будет иметь дело с ASN.1 и вычислением дайджеста сообщения (я предположил, что SHA-1 использовался здесь) для вас.

Если вы все еще действительно хотите знать, как происходит преобразование значений {r, s} в / из ASN.1, посмотрите в источнике DsaDigestSigner. Внутренне он выполняет соответствующее кодирование / декодирование ASN.1, а затем использует класс DsaSigner для низкоуровневой операции sig.

...