2012-03-06 2 views
1

Java/C# 소켓 (Java 서버, C# 클라이언트)을 통해 보내는 모든 데이터를 암호화하고 싶습니다. AES256을 사용하고 싶습니다만, Java와 C#에서 동일한 암호화 된 코드를 생성 할 수 없습니다. 누구든지 저에게 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

+0

내가 시도한 것을 추가했습니다 ... 그리고 아니오, C#/Java 예제에서 많은 정보를 찾을 수 없습니다. – Basaa

+1

같은 문제가있는 것처럼 보입니다. http://stackoverflow.com/q/5295110/55209 –

답변

4

문제는 당신이 ciphermode 또는 자바 코드에서 패딩을 지정하지 않는 것입니다. 이렇게하면 다른 라이브러리와의 상호 운용성이 필요할 때 절대 수행 할 수없는 알고리즘 기본값이 사용됩니다. 이처럼 Cipher를 초기화 :

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

는 자바 PKCS5이 this 대답에 따라 닷넷에서 PKCS7와 호환되어야합니다. CBC를 현명하게 사용하고 있으므로 암호화와 암호 해독에 동일한 초기화 벡터를 사용하도록 코드를 수정해야합니다. 아니요은 비밀 키를 사용해야합니다. IV는 무작위로 생성되어야합니다. cipher.getIV()을 호출하여 Java Cipher이 암호화를 위해 생성 한 IV를 사용할 수 있습니다.

또한 주석에 언급 된 문자 인코딩과 일치하도록주의하십시오.

관련 문제