2012-03-06 149 views
1

我想加密通過Java/C#套接字(Java服務器,C#客戶端)發送的所有數據。 我想使用AES256,但我無法讓Java和C#生成相同的加密代碼。任何人都可以給我兩個例子,1在Java和1在C#中產生相同的結果,並正確地解密結果?C#/ Java | AES256加密/解密

我試了一下,到目前爲止:

public Encrypt(AOBCore instance){ 
    try { 
     String message="This is just an example"; 

      // Get the KeyGenerator 

      KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
      kgen.init(256); // 192 and 256 bits may not be available 


      // Generate the secret key specs. 
      SecretKey skey = kgen.generateKey(); //Cantget 'test' in here... 
      byte[] raw = skey.getEncoded(); 

      SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 


      // Instantiate the cipher 

      Cipher cipher = Cipher.getInstance("AES"); 

      cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 

      byte[] encrypted = 
      cipher.doFinal(message.getBytes()); 
      System.out.println("encrypted string: " + asHex(encrypted)); 

      cipher.init(Cipher.DECRYPT_MODE, skeySpec); 
      byte[] original = 
      cipher.doFinal(encrypted); 
      String originalString = new String(original); 
      System.out.println("Original string: " + 
      originalString + " " + asHex(original)); 
    } catch (Exception e) { 
     instance.logMessage(e.getMessage()); 
    } 
} 

public static String asHex (byte buf[]) { 
     StringBuffer strbuf = new StringBuffer(buf.length * 2); 
     int i; 

     for (i = 0; i < buf.length; i++) { 
     if (((int) buf[i] & 0xff) < 0x10) 
     strbuf.append("0"); 

     strbuf.append(Long.toString((int) buf[i] & 0xff, 16)); 
     } 

     return strbuf.toString(); 
    } 

}

static void Main(string[] args) 
    { 
     while (true) 
     { 
      var plain = Console.ReadLine(); 
      var key = GenerateKey(256); 
      var encoded = Encrypt(plain, key, 256); 
      Console.WriteLine("Encoded: " + encoded); 
      Console.WriteLine(Decrypt(encoded, key, 256)); 
     } 
    } 

    private static string GenerateKey(int keySize) 
    { 
     return "test"; 
    } 

    private static string Encrypt(string plainStr, string completeEncodedKey, int keySize) 
    { 
     RijndaelManaged aesEncryption = new RijndaelManaged(); 
     aesEncryption.KeySize = keySize; 
     aesEncryption.BlockSize = 256; 
     aesEncryption.Mode = CipherMode.CBC; 
     aesEncryption.Padding = PaddingMode.PKCS7; 
     aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[0]); 
     aesEncryption.Key = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[1]); 
     byte[] plainText = ASCIIEncoding.UTF8.GetBytes(plainStr); 
     ICryptoTransform crypto = aesEncryption.CreateEncryptor(); 
     // The result of the encryption and decryption    
     byte[] cipherText = crypto.TransformFinalBlock(plainText, 0, plainText.Length); 
     return Convert.ToBase64String(cipherText); 
    } 

    private static string Decrypt(string encryptedText, string completeEncodedKey, int keySize) 
    { 
     RijndaelManaged aesEncryption = new RijndaelManaged(); 
     aesEncryption.KeySize = keySize; 
     aesEncryption.BlockSize = 128; 
     aesEncryption.Mode = CipherMode.CBC; 
     aesEncryption.Padding = PaddingMode.PKCS7; 
     aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[0]); 
     aesEncryption.Key = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[1]); 
     ICryptoTransform decrypto = aesEncryption.CreateDecryptor(); 
     byte[] encryptedBytes = Convert.FromBase64CharArray(encryptedText.ToCharArray(), 0, encryptedText.Length); 
     return ASCIIEncoding.UTF8.GetString(decrypto.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length)); 
    } 
+1

你應該展示你到目前爲止所嘗試過的 - 這不是一個代碼工廠,因特網提供了大量的例子。 – home 2012-03-06 13:01:24

+0

添加了我嘗試過的...並且不,我在C#/ Java示例中找不到很多信息。 – Basaa 2012-03-06 13:05:51

+1

看起來像你有同樣的問題http://stackoverflow.com/q/5295110/55209 – 2012-03-06 13:14:06

回答

4

的問題是,你是不是指定ciphermode或在Java代碼中的填充。這將使用算法默認值,當需要與其他庫的互操作性時,這絕對不是您想要執行的操作。初始化您Cipher這樣的:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

PKCS5在Java中應根據this答案在.net與PKCS7兼容。由於您明智地使用CBC,您將需要修改代碼以對加密和解密使用相同的初始化向量。你應該不是使用該密鑰。 IV應該是隨機生成的。通過調用cipher.getIV(),您可以使用Java Cipher生成的用於加密的IV。

另外,注意與註釋中提到的字符編碼一致。