2010-02-16 7 views
8

मैं जावा में निम्नलिखित कोड नमूना मिल गया है, और मैं इसे सी # में फिर से लागू करने की जरूरत है:साइन डेटा

PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(pkcs8PrivateKey); 
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
PrivateKey privKey = keyFactory.generatePrivate(privKeySpec); 
Signature sign = Signature.getInstance("MD5withRSA"); 

sign.initSign(privKey); 
sign.update(data); 
byte[] signature = sign.sign(); 

साथ क्या यह संभव है मानक .Net Crypto API, या मुझे BouncyCastle का उपयोग करना चाहिए? धन्यवाद,

बी।

+0

थोड़ा विषय से हटकर है, लेकिन यदि संभव हो, तो आप निश्चित रूप से किसी भी अनुप्रयोगों में MD5 का उपयोग कर – Krystian

+0

'चाहिए' एक मजबूत शब्द है, भले ही MD5 कमजोर साबित हो चुका है कि यह आसानी से तोड़ा जा सकता है (देखें से बचना चाहिए http : //merlot.usc.edu/csac-f06/papers/Wang05a.pdf, विकिपीडिया द्वारा संदर्भित) यह हमेशा निर्णय लेने के लिए प्रोग्रामर तक नहीं है। :-) – Patrick

+0

@ क्रिस्टियन, यह निर्णय लिया गया था जिसने 6 साल पहले इंटरफ़ेस बनाया था :) – balint

उत्तर

3

मैं क्रोम एक्सटेंशन पैक करने के लिए देशी सी # टूल बनाने की कोशिश कर रहा एक बहुत ही समान समस्या में भाग रहा हूं (SHA1 का उपयोग करके, MD5 नहीं, लेकिन यह एक बड़ा अंतर नहीं है)। मेरा मानना ​​है कि मैंने सचमुच .NET: System.Security.Cryptography, BouncyCastle, OpenSSL.Net और Chilkat RSA के लिए हर संभावित समाधान की कोशिश की है।

सबसे अच्छा समाधान शायद चिलकट है; उनका इंटरफ़ेस सबसे साफ और सबसे सरल है, यह अच्छी तरह से समर्थित और अच्छी तरह से प्रलेखित है, और एक लाख उदाहरण हैं। उदाहरण के लिए, यहां कुछ लाइब्रेरी का उपयोग करके कुछ कोड है जो आप चाहते हैं कि बहुत करीब कुछ करता है: http://www.example-code.com/csharp/rsa_signPkcs8.asp। हालांकि, यह मुफ़्त नहीं है (हालांकि $ 150 अनुचित नहीं है, क्योंकि मैंने इसे समझने की कोशिश में 2 दिन जला दिया है, और मैं दिन में $ 75 से थोड़ा अधिक कमाता हूं!)।

एक नि: शुल्क विकल्प के रूप में, जावासाइंस http://www.jensign.com/JavaScience/cryptoutils/index.html पर कई भाषाओं (सी #/नेट सहित) के स्रोत फ़ॉर्म में कई क्रिप्टो उपयोगिताओं की पेशकश करता है। जो आप करने की कोशिश कर रहे हैं उसके लिए सबसे महत्वपूर्ण है opensslkey (http://www.jensign.com/opensslkey/index.html), जो आपको एक .pem फ़ाइल से RSACryptoServiceProvider उत्पन्न करने देगा। तब आप उस प्रदाता का उपयोग अपने कोड पर हस्ताक्षर कर सकते हैं: सुरक्षा के साथ-साथ,

 string pemContents = new StreamReader("pkcs8privatekey.pem").ReadToEnd(); 
     var der = opensslkey.DecodePkcs8PrivateKey(pemContents); 
     RSACryptoServiceProvider rsa = opensslkey.DecodePrivateKeyInfo(der); 

     signature = rsa.SignData(data, new MD5CryptoServiceProvider()); 
+0

मैं चिल्काट का उपयोग करने की अनुशंसा नहीं करूंगा क्योंकि यह मंच निर्भर है (आपको x86 और x64 के लिए अलग-अलग पुस्तकालयों का उपयोग करना होगा) और, आरएसए के बारे में निश्चित नहीं है, लेकिन सममित क्रिप्टोग्राफी का उनका कार्यान्वयन 'System.Security.Cryptography' के साथ संगत नहीं है। – Regent

1

This SO question अपने कोड के पीकेसीएस # 8 भाग का जवाब देते हैं। शेष .NET आरएसए कक्षाएं आंशिक रूप से ओवरलैपिंग कक्षाओं का एक विचित्र झटका है जो समझना बहुत मुश्किल है। यह निश्चित रूप से प्रतीत होता है कि हस्ताक्षर समर्थन RSACryptoServiceProvider और/या RSAPKCS1SignatureFormatter कक्षाओं में से किसी एक में है।

1

अस्वीकरण: मुझे जावा और क्रिप्टोग्राफी पता है, लेकिन सी # और .NET का मेरा ज्ञान बहुत सीमित है। मैं यहां केवल अपने Google-fu कौशल के प्रभाव में लिख रहा हूं।

मान लिया जाये कि आप PKCS # 8 एन्कोड की गई RSA निजी कुंजी को डिकोड कर सकता है, तो, क्या मैं MSDN पर पढ़ा से, कोड के बाकी इस तरह दिखना चाहिए:

byte[] hv = MD5.Create().ComputeHash(data); 
RSACryptoServiceProvider rsp = new RSACryptoServiceProvider(); 
RSAParameters rsp = new RSAParameters(); 
// here fill rsp fields by decoding pkcs8PrivateKey 
rsp.ImportParameters(key); 
RSAPKCS1SignatureFormatter rf = new RSAPKCS1SignatureFormatter(rsp); 
rf.SetHashAlgorithm("MD5"); 
byte[] signature = rf.CreateSignature(hv); 

प्रासंगिक वर्गों में हैं System.Security.Cryptography नामस्थान।

पीकेसीएस # 8 कुंजी ब्लॉब डिकोडिंग (यानी rsp फ़ील्ड में भरने के लिए) के लिए, मुझे this page मिला जो सी # में एक कमांड लाइन उपयोगिता का वर्णन करता है जो कि नौकरी कर सकता है। स्रोत कोड प्रदान किया गया है और एक सी # फ़ाइल है। जो मैंने इसे पढ़ा है, वह कोड पीकेसीएस # 8 फ़ाइल "मैन्युअल रूप से" डीकोड करता है; अप्रत्यक्ष रूप से, इसका मतलब यह होना चाहिए कि कच्चे .NET (2.0) में पीकेसीएस # 8 कुंजी फ़ाइल डिकोडिंग की सुविधा नहीं है (अन्यथा उस उपकरण का लेखक इस तरह के डिकोडिंग को लागू करने की परेशानी के लिए नहीं होता)। अपने काम के लिए, आप उस स्रोत फ़ाइल से उन हिस्सों को खोद सकते हैं जिन्हें आप चाहते हैं, पीईएम और सममित एन्क्रिप्शन के बारे में कुछ भी छोड़ना; आपका एंट्री पॉइंट DecodePrivateKeyInfo() फ़ंक्शन होगा, जो स्पष्ट रूप से एक डीईआर-एन्कोडेड अनएन्क्रिप्टेड पीकेसीएस # 8 फ़ाइल की अपेक्षा करता है, जैसे कि जावा के PKCS8EncodedKeySpec

+0

टिम, शांत रहें, मैं सभी उत्तरों की जांच कर रहा हूं – balint

9

एक और तरीका है सीएनजी (क्रिप्टोग्राफी अगली पीढ़ी) का प्रयोग है।से CodePlex

क्रिप्टोग्राफी DLL तो फिर तुम लिख सकते हैं: साइमन Mourier को

byte[] dataToSign = Encoding.UTF8.GetBytes("Data to sign"); 
using (CngKey signingKey = CngKey.Import(pkcs8PrivateKey, CngKeyBlobFormat.Pkcs8PrivateBlob)) 
    using (RSACng rsa = new RSACng(signingKey)) 
    { 
    rsa.SignatureHashAlgorithm = CngAlgorithm.MD5; 
    return rsa.SignData(dataToSign); 
    } 

अपडेट किया धन्यवाद: नेट 4.6 के साथ, आप अब एक अलग पुस्तकालय

+0

इससे पहले कभी नहीं सुना! क्या आप अतिरिक्त उदाहरणों के बारे में जानते हैं? – LamonteCristo

+0

एमएसडीएन पत्रिका में उदाहरण हैं: http://msdn.microsoft.com/en-us/magazine/cc163389.aspx – Timores

+1

नोट यह अब .NET Framework 4.6 में शामिल है। यह वास्तव में आज के .NET विकास के लिए जाने का तरीका है। –

0

जरूरत है आप इस कोड का उपयोग कर सकते हैं। सबसे पहले आपको http://www.bouncycastle.org/csharp/ से "BouncyCastle.Crypto.dll" डाउनलोड करना चाहिए।

/// <summary> 
/// MD5withRSA Signing 
/// https://www.vrast.cn 
/// keyle_xiao 2017.1.12 
/// </summary> 
public class MD5withRSASigning 
{ 
    public Encoding encoding = Encoding.UTF8; 
    public string SignerSymbol = "MD5withRSA"; 

    public MD5withRSASigning() { } 

    public MD5withRSASigning(Encoding e, string s) 
    { 
     encoding = e; 
     SignerSymbol = s; 
    } 

    private AsymmetricKeyParameter CreateKEY(bool isPrivate, string key) 
    { 
     byte[] keyInfoByte = Convert.FromBase64String(key); 

     if (isPrivate) 
      return PrivateKeyFactory.CreateKey(keyInfoByte); 
     else 
      return PublicKeyFactory.CreateKey(keyInfoByte); 
    } 

    public string Sign(string content, string privatekey) 
    { 
     ISigner sig = SignerUtilities.GetSigner(SignerSymbol); 

     sig.Init(true, CreateKEY(true, privatekey)); 

     var bytes = encoding.GetBytes(content); 

     sig.BlockUpdate(bytes, 0, bytes.Length); 
     byte[] signature = sig.GenerateSignature(); 


     /* Base 64 encode the sig so its 8-bit clean */ 
     var signedString = Convert.ToBase64String(signature); 

     return signedString; 
    } 

    public bool Verify(string content, string signData, string publickey) 
    { 
     ISigner signer = SignerUtilities.GetSigner(SignerSymbol); 

     signer.Init(false, CreateKEY(false, publickey)); 

     var expectedSig = Convert.FromBase64String(signData); 

     /* Get the bytes to be signed from the string */ 
     var msgBytes = encoding.GetBytes(content); 

     /* Calculate the signature and see if it matches */ 
     signer.BlockUpdate(msgBytes, 0, msgBytes.Length); 
     return signer.VerifySignature(expectedSig); 
    } 
} 
संबंधित मुद्दे