2017-03-02 25 views
0

我的後端服務器基於.NET。 在服務器上有使用Rfc2898DeriveBytes加密Rfc2898DeriveBytes for java?

這是淨

的代碼
public static string Encrypt(string clearText) 
    { 
     string EncryptionKey = "abc123"; 
     byte[] clearBytes = Encoding.Unicode.GetBytes(clearText); 
     using (Aes encryptor = Aes.Create()) 
     { 
      Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }); 
      encryptor.Key = pdb.GetBytes(32); 
      encryptor.IV = pdb.GetBytes(16); 
      using (MemoryStream ms = new MemoryStream()) 
      { 
       using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)) 
       { 
        cs.Write(clearBytes, 0, clearBytes.Length); 
        cs.Close(); 
       } 
       clearText = Convert.ToBase64String(ms.ToArray()); 
      } 
     } 
     return clearText; 
    } 

我寫的客戶端JAVA。這是代碼

try { 
     String encryptKey = "abc123"; 
     byte[] salt = new byte[]{0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76}; 
     SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
     KeySpec spec = new PBEKeySpec(encryptKey.toCharArray(), salt, 1024, 128); 
     SecretKey tmp = factory.generateSecret(spec); 
     SecretKeySpec secret = new SecretKeySpec(tmp.getEncoded(), "AES"); 
     System.out.println("Key:" + Base64.encodeToString(secret.getEncoded(), Base64.DEFAULT)); 


     String cleartext = "12345"; 
     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE, secret); 
     AlgorithmParameters params = cipher.getParameters(); 
     byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV(); 
     byte[] ciphertext = cipher.doFinal(cleartext.getBytes("UTF-8")); 
     System.out.println("IV:" + Base64.encodeToString(iv, Base64.DEFAULT)); 
     System.out.println("Cipher text:" + Base64.encodeToString(ciphertext, Base64.DEFAULT));; 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeySpecException e) { 
     e.printStackTrace(); 
    } catch (NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } catch (InvalidKeyException e) { 
     e.printStackTrace(); 
    } catch (InvalidParameterSpecException e) { 
     e.printStackTrace(); 
    } catch (IllegalBlockSizeException e) { 
     e.printStackTrace(); 
    } catch (BadPaddingException e) { 
     e.printStackTrace(); 
    } catch (UnsupportedEncodingException e) { 
     e.printStackTrace(); 
    } 

我在java中得不到與.Net相同的結果。 服務器上的12345的加密值爲dAQWIrbtHv/eDbu+4oJD0g==

雖然我得到tcvGLK5r99jt6PFLALpRfQ==

什麼是修復我需要申請?

+0

你需要從Java中的PBKDF2中獲得IV,但是你總是生成一個隨機的IV。 –

+0

@ArtjomB。你可以分享代碼嗎? – WISHY

+0

如果你寫了所有的代碼,那麼你也可以進行更改?還是你只是複製並粘貼你的安全代碼? –

回答

2

Rfc2898DeriveBytes的默認迭代計數爲1000,而不是1024(每the source)。

我不知道PBEKeySpeckeyLength值是以字節爲單位還是以位爲單位,但是如果是在Java中請求128位而在C#中則是256(32字節)。

呃,實際上,你已經要求C#中的384位。因爲前256個變成你的密碼密鑰,那麼接下來的128個變成你的IV(你似乎讓它在Java中隨機生成)。

因此,您可能需要詢問384位,請撥getEncoded(),將答案分爲32字節密鑰和16字節IV,然後從此處繼續。

+0

我應該做什麼改變Java代碼。 – WISHY