2010-07-09 14 views
13

में पीबीकेडीएफ 2 मैं पीबीकेडीएफ 2 कुंजी व्युत्पन्न कैसे करें, यह जानने के लिए सी # बाउंसी कैसल एपीआई के आसपास गड़बड़ कर रहा हूं।बाउंसी कैसल सी #

मैं अभी वास्तव में अनजान हूं।

मैंने Pkcs5S2ParametersGenerator.cs और PBKDF2Params.cs फ़ाइलों के माध्यम से पढ़ने की कोशिश की लेकिन मैं वास्तव में यह नहीं समझ सकता कि इसे कैसे किया जाए।

मैंने अभी तक किए गए शोध के अनुसार, पीबीकेडीएफ 2 को एक स्ट्रिंग (या char []) की आवश्यकता है जो पासवर्ड, नमक और पुनरावृत्ति गणना है।

अब तक का सबसे आशाजनक और सबसे स्पष्ट मैं अब तक आया हूं पीबीकेडीएफ 2 पैराम्स और पीकेसीएस 5 एस 2 पैरामीटर जेनरेटर।

इनमें से कोई भी स्ट्रिंग या चार स्वीकार नहीं कर रहा है []।

क्या किसी ने इसे सी # में किया है या इसके बारे में कोई सुराग है? या शायद किसी ने जावा में BouncyCastle लागू किया है और मदद कर सकता है?

अग्रिम में एक बहुत :)

अद्यतन Thanx: मैंने पाया है कि कैसे Bouncy कैसल में यह करने के लिए। उत्तर के लिए नीचे देखें :)

उत्तर

13

कोड के माध्यम से घंटों के घंटों और घंटों के बाद, मैंने पाया कि ऐसा करने का सबसे आसान तरीका है Pkcs5S2ParametersGenerator.cs में कोड के कुछ हिस्सों को लेना और अपनी खुद की कक्षा बनाना अन्य BouncyCastle API का उपयोग करें। यह डॉट नेट कॉम्पैक्ट फ्रेमवर्क (विंडोज मोबाइल) के साथ पूरी तरह से काम करता है। यह Rfc2898DeriveBytes क्लास के बराबर है जो डॉट नेट कॉम्पैक्ट फ्रेमवर्क 2.0/3.5 में मौजूद नहीं है। ठीक है, शायद नहीं सटीक बराबर लेकिन करता है काम :)

यह वह जगह है PKCS5/PKCS # 5

पीआरएफ (छद्म यादृच्छिक समारोह) जो HMAC-SHA1

पहली चीज़ हो जाएगा प्रयोग किया जाता है, प्रथम। http://www.bouncycastle.org/csharp/ से बाउंसी कैसल संकलित असेंबली डाउनलोड करें, अपनी परियोजना के संदर्भ के रूप में BouncyCastle.Crypto.dll जोड़ें।

इसके बाद नीचे दिए गए कोड के साथ नई कक्षा फ़ाइल बनाएं।

using System; 
using Org.BouncyCastle.Crypto; 
using Org.BouncyCastle.Crypto.Parameters; 
using Org.BouncyCastle.Crypto.Digests; 
using Org.BouncyCastle.Crypto.Macs; 
using Org.BouncyCastle.Math; 
using Org.BouncyCastle.Security; 

namespace PBKDF2_PKCS5 
{ 
    class PBKDF2 
    { 

     private readonly IMac hMac = new HMac(new Sha1Digest()); 

     private void F(
      byte[] P, 
      byte[] S, 
      int c, 
      byte[] iBuf, 
      byte[] outBytes, 
      int outOff) 
     { 
      byte[] state = new byte[hMac.GetMacSize()]; 
      ICipherParameters param = new KeyParameter(P); 

      hMac.Init(param); 

      if (S != null) 
      { 
       hMac.BlockUpdate(S, 0, S.Length); 
      } 

      hMac.BlockUpdate(iBuf, 0, iBuf.Length); 

      hMac.DoFinal(state, 0); 

      Array.Copy(state, 0, outBytes, outOff, state.Length); 

      for (int count = 1; count != c; count++) 
      { 
       hMac.Init(param); 
       hMac.BlockUpdate(state, 0, state.Length); 
       hMac.DoFinal(state, 0); 

       for (int j = 0; j != state.Length; j++) 
       { 
        outBytes[outOff + j] ^= state[j]; 
       } 
      } 
     } 

     private void IntToOctet(
      byte[] Buffer, 
      int i) 
     { 
      Buffer[0] = (byte)((uint)i >> 24); 
      Buffer[1] = (byte)((uint)i >> 16); 
      Buffer[2] = (byte)((uint)i >> 8); 
      Buffer[3] = (byte)i; 
     } 

     // Use this function to retrieve a derived key. 
     // dkLen is in octets, how much bytes you want when the function to return. 
     // mPassword is the password converted to bytes. 
     // mSalt is the salt converted to bytes 
     // mIterationCount is the how much iterations you want to perform. 


     public byte[] GenerateDerivedKey(
      int dkLen, 
      byte[] mPassword, 
      byte[] mSalt, 
      int mIterationCount 
      ) 
     { 
      int hLen = hMac.GetMacSize(); 
      int l = (dkLen + hLen - 1)/hLen; 
      byte[] iBuf = new byte[4]; 
      byte[] outBytes = new byte[l * hLen]; 

      for (int i = 1; i <= l; i++) 
      { 
       IntToOctet(iBuf, i); 

       F(mPassword, mSalt, mIterationCount, iBuf, outBytes, (i - 1) * hLen); 
      } 

     //By this time outBytes will contain the derived key + more bytes. 
     // According to the PKCS #5 v2.0: Password-Based Cryptography Standard (www.truecrypt.org/docs/pkcs5v2-0.pdf) 
     // we have to "extract the first dkLen octets to produce a derived key". 

     //I am creating a byte array with the size of dkLen and then using 
     //Buffer.BlockCopy to copy ONLY the dkLen amount of bytes to it 
     // And finally returning it :D 

     byte[] output = new byte[dkLen]; 

     Buffer.BlockCopy(outBytes, 0, output, 0, dkLen); 

     return output; 
     } 


    } 
} 

तो इस फ़ंक्शन का उपयोग कैसे करें? सरल! :) यह एक बहुत ही सरल उदाहरण है जहां उपयोगकर्ता द्वारा पासवर्ड और नमक प्रदान किया जाता है।

private void cmdDeriveKey_Click(object sender, EventArgs e) 
     { 
      byte[] salt = ASCIIEncoding.UTF8.GetBytes(txtSalt.Text); 

      PBKDF2 passwordDerive = new PBKDF2(); 


     // I want the key to be used for AES-128, thus I want the derived key to be 
     // 128 bits. Thus I will be using 128/8 = 16 for dkLen (Derived Key Length) . 
     //Similarly if you wanted a 256 bit key, dkLen would be 256/8 = 32. 

      byte[] result = passwordDerive.GenerateDerivedKey(16, ASCIIEncoding.UTF8.GetBytes(txtPassword.Text), salt, 1000); 

      //result would now contain the derived key. Use it for whatever cryptographic purpose now :) 
      //The following code is ONLY to show the derived key in a Textbox. 

      string x = ""; 

      for (int i = 0; i < result.Length; i++) 
      { 
       x += result[i].ToString("X"); 
      } 

      txtResult.Text = x; 

     } 

यह जांचने के लिए कि यह सही है या नहीं? एक ऑनलाइन PBKDF2 http://anandam.name/pbkdf2/

की जावास्क्रिप्ट कार्यान्वयन मैं संगत परिणामों :) अगर कोई एक गलत परिणाम :)

आशा इस मदद करता है किसी को :)

अद्यतन हो रही है कृपया रिपोर्ट मिल गया है: की पुष्टि की परीक्षण वेक्टर के साथ काम कर यहाँ प्रदान

http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-00

updat ई: वैकल्पिक रूप से, नमक के लिए हम एक RNGCryptoServiceProvider उपयोग कर सकते हैं। System.Security.Cryptography नामस्थान का संदर्भ लें सुनिश्चित करें।

RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();   

byte[] salt = new byte[16]; 

rng.GetBytes(salt); 
+1

आप बहुत तेजी से अपने खुद के सवालों का जवाब! –

+1

आपने अभी मुझे बहुत समय बचाया है। धन्यवाद! – John

+0

@ जॉन: किसी भी मदद की खुशी है :) –

1

मुझे बस यह समस्या थी, और एक और सीधा दृष्टिकोण मिला। कम से कम Bouncy कैसल 1.7 के रूप में आप (Org.BouncyCastle.Crypto का उपयोग कर VB में) इस तरह यह कर सकते हैं:

Dim bcKeyDer As New Generators.Pkcs5S2ParametersGenerator() 
bcKeyDer.Init(password, salt, keyIterations) 
Dim bcparam As Parameters.KeyParameter = bcKeyDer.GenerateDerivedParameters("aes256", 256) 
Dim key1() As Byte = bcparam.GetKey() 

मैं नेट के System.Security.Cryptography के खिलाफ इस परीक्षण किया है, और यह काम करता है!

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