2009-10-27 10 views
5

उपयोग कर रहा है मैं सी # में एक DSA हस्ताक्षर कैसे सत्यापित कर सकते हैं सत्यापित करें?सी # में एक DSA हस्ताक्षर कि संख्या/डीईआर इनकोडिंग ASN.1 प्रारूप

को देखते हुए:

  • संदेश पाठ,
  • एक हस्ताक्षरित डाइजेस्ट (आम तौर पर ASN.1 डीईआर प्रारूप),
  • सार्वजनिक कुंजी (एक हस्ताक्षरित X.509 प्रमाणपत्र, पीईएम या डीईआर में प्रारूप)

मैं दृष्टिकोण के एक नंबर की कोशिश की है, लेकिन कोई सफलता नहीं मिली है:

  • OpenSSL.NET: पुस्तकालय के साथ विभिन्न अजीब त्रुटियों; मुझे open thread running with the author over on SourceForge मिला है लेकिन अभी तक इसे हल करने में सक्षम नहीं हैं।

  • माइक्रोसॉफ्ट .NET API: तुलना के लिए डीईआर हस्ताक्षर को अनपैक नहीं कर सकता है। एक DSA हस्ताक्षर 40 बाइट (दो 20-बाइट पूर्णांकों) है, लेकिन दो पूर्णांकों का एक DER- एन्कोड अनुक्रम के रूप में प्रस्तुत किया जाता है, तो कुल लंबाई 46 से 48 बाइट (एक त्वरित अवलोकन के लिए this post देखें।) जबकि नेट से रेंज कर सकते ASN.1/DER को पार्स करने के लिए कोड शामिल है (क्योंकि यह डीईआर प्रारूप में प्रमाणपत्र पढ़ सकता है), इसे गहरा दफनाया गया है, और इसका उपयोग करने का कोई तरीका नहीं है ताकि आप ASN.1/DER एन्कोडेड सिग से 40 बाइट्स को सही तरीके से पुनर्प्राप्त कर सकें। यह समस्या अगले विकल्प के लिए मुझे नेतृत्व किया ...

  • BouncyCastle: Org.BouncyCastle.Asn1 कार्यों के उपयोग के माध्यम, मैं ASN.1 हस्ताक्षर पार्स और इसे खींच में घटक आर और एस पूर्णांक मूल्यों है सकते हैं। लेकिन जब मैं इन्हें हस्ताक्षर सत्यापन दिनचर्या में पास करता हूं, तो यह कोई स्पष्टीकरण नहीं दे रहा है। मुझे यकीन है कि अगर मैंने कुछ गलत कर रहा हूँ नहीं कर रहा हूँ, क्योंकि सी # एपीआई पूरी तरह से गैर-दस्तावेजी है, और जावा संस्करण मुश्किल से प्रलेखित है (लेकिन कोई उदाहरण या विधिपत्र जानकारी है कि मैं मिल सकता है।)

मैं इस समस्या पर खुद को लगभग एक सप्ताह तक फेंक रहा हूं। मुझे पता है कि किसी ने इसे पहले किया होगा, लेकिन मुझे कोई पूरा/काम करने वाला उदाहरण नहीं मिला है।

मैं तीन सी # यहां बैठे परियोजनाओं मिल गया है, प्रत्येक 95% पूरा, लेकिन एक महत्वपूर्ण दोष यह विफल करने का कारण बनता है के साथ। किसी भी कामकाजी उदाहरण कोड की सराहना की जाएगी।

संपादित करें: यहाँ एक हस्ताक्षर बात की पुष्टि कैसे कोशिश कर रहा हूँ का एक उदाहरण है, Base64 और ASCII हेक्स में बदल जाती यह postable बनाने के लिए। यह विशेष रूप से एक 47 बाइट्स है, लेकिन एक उचित पार्सर अभी भी यह स्वीकार करना चाहिए, अधिक जानकारी के लिए डीईआर कल्पना को पढ़ने

Base64: MC0CFQCUgq2DEHWzp3O4nOdo38mDu8mStwIUadZmbin7BvXxpeoJh7dhquD2CTM= 

ASCII Hex: 302d0215009482ad831075b3a773b89ce768dfc983bbc992b7021469d6666e29fb06f5f1a5ea0987b761aae0f60933 

संरचना (संख्या/डीईआर एक प्रमुख 00 पर हस्ताक्षर की पुष्टि करने के अगर MSB 1 है कहते हैं) डीईआर स्पेक प्रति है; इस प्रकार यह पार्स करता है:

30 2d: sequence, length 45 (may vary from 44 to 46) 
02 15: integer, length 21 (first byte is 00 to confirm sign) 
    009482ad831075b3a773b89ce768dfc983bbc992b7 
02 14: integer, length 20 (leading 00 not necessary for this one) 
    69d6666e29fb06f5f1a5ea0987b761aae0f60933 

मेरे अपने डीईआर पार्सर लेखन वास्तव में एक विकल्प नहीं है, त्रुटि के लिए बहुत ज्यादा कमरे है और वहाँ इस ठीक से करने के लिए एक तरह से हो गया है।

+0

मैं सोच रहा था कि क्या आप मुझे एक पक्ष कर सकते हैं और "सी # में डीएसए हस्ताक्षर सत्यापित करें" से "एएसएन.1 प्रारूप के साथ सी # में डीएसए हस्ताक्षर सत्यापित करें" या शीर्षक की तरह से शीर्षक बदल सकते हैं। लोगों को थोड़ा सा खोजने में मदद कर सकते हैं। – Greg

+0

बस एक टिप्पणी के रूप में; मैं दूसरी तरफ जा रहा हूं (जावा में एक हस्ताक्षर सत्यापित करें जो .NET में बनाया गया था); मुझे डीईआर प्रारूप में .NET डीएसए प्रारूप (जो केवल 40 बाइट्स में आर || है) से एक कनवर्टर लिखना पड़ा। जो मैंने यहां पाया है उसके अनुसार (http://www.mombu.com/microsoft/security-crypto/t-dsa-ignature-format-674106.html) डीईआर प्रारूप आर और एस को बड़े-एंडियन होने की उम्मीद करता है लेकिन वह नहीं मैं बिल्कुल काम नहीं करता इसलिए मैंने इसे थोड़ा-सा अंतराल के रूप में छोड़ा और यह काम करता है ... मुझे इस पर कुछ भी स्पष्ट नहीं मिला है; यह बड़ा होना चाहिए- या छोटे-छोटे ... अगर कोई जानता है तो कृपया चुप रहो! – SonarJetLens

उत्तर

1

कोड का एक टुकड़ा है कि एक DSA हस्ताक्षर को सत्यापित करता NSsh परियोजना में पाया जा सकता है। यह आपकी सटीक जरूरतों के अनुरूप नहीं है क्योंकि सार्वजनिक कुंजी को एक्स से नहीं खींचा जाता है।50 9 प्रमाणपत्र लेकिन यह आपको एक शुरुआती बिंदु दे सकता है।

+0

जहां तक ​​मैं देख सकता हूं, यह आंतरिक रूप से हस्ताक्षर उत्पन्न कर रहा है: हस्ताक्षरOfH = hostKey.Sign (एच); मुझे बाहरी रूप से जेनरेट किए गए हस्ताक्षर को पढ़ने की आवश्यकता है, जो ASN.1 समस्या का कारण बनता है (अद्यतन पोस्ट में थोड़ा और वर्णित है।) – andersop

1

एक और अच्छा उदाहरण DotNetAutoUpdate कोड है। यह आरएसए का उपयोग करता है लेकिन डीएसए पर स्विच करना काफी आसान होना चाहिए। विशेष रूप से इस फाइल पर एक नजर है:

http://code.google.com/p/dotnetautoupdate/source/browse/trunk/source/DotNetAutoUpdate/UpdateKeys.cs


संपादित करें: MSDN पर

var sha1 = new SHA1Managed(); 
var hash = sha1.ComputeHash(inputStream); 

var signatureFormatter = new DSASignatureDeformatter(dsa); 
signatureFormatter.SetHashAlgorithm("SHA1"); 
bool valid = signatureFormatter.VerifySignature(hash, signature); 

अधिक विवरण: मूल रूप से आप इस के लिए कुछ इसी तरह चाहते हैं।


संपादित करें:

  • वहाँ पढ़ने ASN1
  • के लिए एक वर्ग है 509 cerficiates पढ़ने के लिए भी एक assembly है: एक अन्य विकल्प Mono.Security पुस्तकालयों है।

मुझे यकीन है कि अगर मदद करता है नहीं कर रहा हूँ ...

+0

.NET कार्यान्वयन के साथ समस्या यह है कि यह ASN.1 प्रारूप का विश्लेषण नहीं कर सकता हस्ताक्षर - मैं ऊपर दिए गए उदाहरण में "हस्ताक्षर" वस्तु उत्पन्न नहीं कर सकता। – andersop

+0

@andersop क्या आप एएसएन .1 हस्ताक्षर का एक उदाहरण पोस्ट कर सकते हैं? –

+0

@Luke Quinane: निश्चित रूप से, मैंने इसे ओपी में संपादित किया क्योंकि टिप्पणियां प्रारूपण का समर्थन नहीं करती हैं। – andersop

0

जेएफवाईआई: कभी-कभी मुझे ओपनएसएसएल कमांड लाइन टूल द्वारा उत्पन्न 45-बाइट डीईआर डीएसए हस्ताक्षर (इंटेगर्स में से 1 9 बाइट्स 20 नहीं) देखते हैं। और ऐसा लगता है कि 44 बाइट्स (दोनों 1 9 बाइट्स) हो सकते हैं, इसलिए आप बेहतर 46 से 48 के बजाय 6 से 48 बाइट्स की अपेक्षा करते हैं .-)

1

बाउंसीकास्टल (v1.7) का उपयोग करके, मैं कर सकता हूं ऐसा करें (निश्चित रूप से त्रुटि जांचना न भूलें):

using System.Security.Cryptography; 
using System.Security.Cryptography.X509Certificates; 
using Org.BouncyCastle.Asn1; 

byte[] signature = ReadFile("signature.bin"); 
byte[] dataToVerify = ReadFile("data.bin"); 
byte[] rawPublicKey = KeyResources.publickey; // My public key is in a resource 

var x509 = new X509Certificate2(rawPublicKey); 
var dsa = x509.PublicKey.Key as DSACryptoServiceProvider; 

// extract signature components from ASN1 formatted signature 
DSASignatureDeformatter DSADeformatter = new DSASignatureDeformatter(dsa); 
DSADeformatter.SetHashAlgorithm("SHA1"); 

Asn1InputStream bIn = new Asn1InputStream(new MemoryStream(signature)); 
DerSequence seq = bIn.ReadObject() as DerSequence; 

var r11 = seq[0].GetEncoded(); 
var r21 = seq[1].GetEncoded(); 

byte[] p1363 = new byte[40]; 
Array.Copy(r11, r11.Length - 20, p1363, 0, 20); 
Array.Copy(r21, r21.Length - 20, p1363, 20, 20); 

// and finally we can verify 
if (!DSADeformatter.VerifySignature(new SHA1CryptoServiceProvider().ComputeHash(dataToVerify), p1363)) 
{ 
    // Noo, mismatch! 
} 

मेरा हस्ताक्षर.बीबी ओपनएसएसएल का उपयोग करके उत्पन्न होता है, उदाहरण के लिए openssl dgst -sha1 -sign private.key data.bin > signature.bin

संबंधित मुद्दे