2013-02-11 171 views
1

我想在C#中複製這個Java代碼。Bouncy Castle PBEWITHSHA256AND256BITAES加密C#

 BASE64Decoder dec = new BASE64Decoder(); 
    byte[] salt = null; 
    try { 
     salt = dec.decodeBuffer(saltStr); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    Security.insertProviderAt(new BouncyCastleProvider(), 1); 
    String alg = "PBEWITHSHA256AND256BITAES-CBC-BC"; 
    int derivedKeyLength = 256; 
    int iterations = 20000; 
    KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations, 
      derivedKeyLength); 
    try { 
     SecretKeyFactory f = SecretKeyFactory.getInstance(alg); 
     byte[] result = f.generateSecret(spec).getEncoded(); 
     BASE64Encoder endecoder = new BASE64Encoder(); 
     System.out.println(endecoder.encode(result)); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeySpecException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

這是我到目前爲止,但它是失敗的。我是Crypto世界的新手(所以可能有更簡單的方法來做到這一點,我不知道),所以任何幫助將不勝感激。謝謝!

 var iterations = 20000; 
     PbeParametersGenerator pGen = new Pkcs12ParametersGenerator(new Sha256Digest()); 
     pGen.Init(Encoding.ASCII.GetBytes(password), Convert.FromBase64String(salt), iterations); 
     ICipherParameters par = pGen.GenerateDerivedParameters("AES256", 256); 
     IBufferedCipher c = CipherUtilities.GetCipher("PBEWITHSHA256AND256BITAES-CBC-BC"); 
     Console.WriteLine(c.AlgorithmName); 
     c.Init(true, par); 
     byte[] enc = c.DoFinal(Convert.FromBase64String(salt)); 
     Console.WriteLine("The output is :"); 
     Console.WriteLine(Convert.ToBase64String(enc)); 

的問題是,加密後的結果是不是在Java和C#用相同的密碼,相同的鹽和相同的迭代次數相同。

更新:

的問題是Java代碼(不是我寫的,是不是做的密碼加密),它只是產生的關鍵參數。此代碼將提供與Java代碼相同的輸出。

 var iterations = 20000; 
     var sltBytes = Convert.FromBase64String(salt); 
     byte[] byteSalt = Convert.FromBase64String(salt); 
     byte[] pwdb = PbeParametersGenerator.Pkcs12PasswordToBytes(password.ToCharArray()); 
     PbeParametersGenerator pGen = new Pkcs12ParametersGenerator(new Sha256Digest()); 
     pGen.Init(pwdb, Convert.FromBase64String(salt), iterations); 
     var par = (ParametersWithIV)pGen.GenerateDerivedParameters("AES256", 256, 128); 
     var kpar = (KeyParameter)par.Parameters; 
     byte[] by = kpar.GetKey(); 
     Console.WriteLine(Convert.ToBase64String(by)); 
+2

什麼是失敗的導出密鑰的長度,我的問題是什麼? – ALOToverflow 2013-02-11 17:42:38

+1

對不起,我添加的問題是Java版本和C#版本的結果是不同的,具有相同的參數。 – pwfixed 2013-02-11 18:15:31

+0

你能否驗證兩個版本的'salt'結果是一樣的? – EtherDragon 2013-02-11 18:37:13

回答

2

您對GenerateDerivedParameters("AES256", 256)調用指定比在Java中derivedKeyLength不同的密鑰長度。

+0

+1因爲比我快幾秒。 – EtherDragon 2013-02-11 18:28:32

+0

其實很好,趕上!但那不是。結果仍然不同。 – pwfixed 2013-02-11 18:28:45

+0

在這種情況下,鑑於代碼本身並沒有明確的問題,可能鹽並不像您想象的那樣完全相同。另外,我對此不是100%確定,但是與Java中的toCharArray()相比,Encoding.ASCII.GetBytes可能會給出稍微不同的輸出。 – doctorless 2013-02-11 18:44:59

1

我覺得這是你的問題:

在這裏,您指定的128

int derivedKeyLength = 128; 
... 
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, iterations, 
     derivedKeyLength); 

導出密鑰的長度在此指定的256

ICipherParameters par = pGen.GenerateDerivedParameters("AES256", 256); 
相關問題