2012-03-06 111 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。

另外,注意与注释中提到的字符编码一致。