2014-03-05 2 views
3

Android 앱에서 문자열을 암호화하고 ASP.Net 서버에서 해독하려고합니다. 오류는 발생하지 않지만 암호 해독은 실제 결과를 반환하지 않습니다.AES 암호 해독이 잘못된 결과를 나타냅니다.

public void clckBtn(View v) { 
     try { 
      SecretKeySpec skeySpec = new SecretKeySpec(
        "MyDifficultPassw".getBytes(), "AES"); 
      Cipher cipher = Cipher.getInstance("AES"); 
      cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 
      byte[] encrypted = cipher.doFinal("tryToEncrypt".getBytes()); 
      System.out.println(toHex(encrypted)); 

     } catch (Exception e) { 
      System.out.println(e.toString()); 
     } 

    } 


    public static String toHex(byte[] buf) { 
     if (buf == null) 
      return ""; 
     StringBuffer result = new StringBuffer(2 * buf.length); 
     for (int i = 0; i < buf.length; i++) { 
      appendHex(result, buf[i]); 
     } 
     return result.toString(); 
    } 

    private final static String HEX = "ABCDEF"; 

    private static void appendHex(StringBuffer sb, byte b) { 
     sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f)); 
    } 

출력은 : CE3E99F50E6D30201E38D4955F07BA7C

Asp.Net 측 :

Asp.Net AES 클래스
protected void Page_Load(object sender, EventArgs e) 
     { 
      using (Aes myAes = Aes.Create()) 
      { 
       string asd = DecryptStringFromBytes_Aes(GetBytes("CE3E99F50E6D30201E38D4955F07BA7C"), GetBytes("MyDifficultPassw"), myAes.IV); 
       int we = 0; 
      } 

     } 

     static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key 
, byte[] IV) 
     { 
      // Check arguments. 
      if (cipherText == null || cipherText.Length <= 0) 
       throw new ArgumentNullException("cipherText"); 
      if (Key == null || Key.Length <= 0) 
       throw new ArgumentNullException("Key"); 
      if (IV == null || IV.Length <= 0) 
       throw new ArgumentNullException("Key"); 

      // Declare the string used to hold 
      // the decrypted text. 
      string plaintext = null; 

      // Create an Aes object 
      // with the specified key and IV. 
      using (Aes aesAlg = Aes.Create()) 
      { 
       aesAlg.Key = Key; 
       aesAlg.IV = IV; 
       aesAlg.Padding = PaddingMode.None; 

       // Create a decrytor to perform the stream transform. 
       ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key 
, aesAlg.IV); 



       // Create the streams used for decryption. 
       using (MemoryStream msDecrypt = new MemoryStream(cipherText)) 
       { 

        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt 
, decryptor, CryptoStreamMode.Read)) 
        { 

         using (StreamReader srDecrypt = new StreamReader(
csDecrypt)) 
         { 

          // Read the decrypted bytes from the decrypting 

          // and place them in a string. 
          plaintext = srDecrypt.ReadToEnd(); 
         } 
        } 
       } 

      } 

      return plaintext; 

     } 

     static byte[] GetBytes(string str) 
     { 
      byte[] bytes = new byte[str.Length * sizeof(char)]; 
      System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length); 
      return bytes; 
     } 

는 IV (초기화 벡터)를 필요로 여기 안드로이드 측이다. 안드로이드에는 그런 것이 없다. 나는 그 문제가 그것에 관한 것이라고 생각한다.

+0

기본적으로 키, IV, 패딩, 모드와 일치하는지 확인해야합니다. 나는 안드로이드를 프로그래밍하지 않았지만 구글에 대한 빠른 검색은 나를 [this] (http://stackoverflow.com/a/16854800/706456)로 지적했다. 어쩌면 거기에서 해결책을 얻을 수 있습니다. – oleksii

+1

Java 코드에서 ECB 모드를 사용하고 .NET 코드에서 CBC 모드를 사용하고 있습니다. 또한, 나는이 코드가 실제로 당신이 무엇을했는지 성취하지 않을 것이라고 생각한다. ([관련 질문] (http://security.stackexchange.com/questions/52584/why-can-we-still-crack-snapchat-photos- 루비의 12 행)). 아마도 [TLS] (http://en.wikipedia.org/wiki/Transport_Layer_Security)가 더 적합할까요? – ntoskrnl

답변

0

내 코드에 무슨 문제가 있는지 잘 모르겠습니다. 어쩌면 @ntoskrnl이 옳았다. 그럼에도 불구하고 나는 그 모범을 보았고 효과가 있었다. There is the code, 나는 따라 갔다. 여기에도 전체 코드를 제공하고 있습니다. 경우에는 누군가가 그것을 필요 :

자바 측 :

import java.security.InvalidAlgorithmParameterException; 
import java.security.InvalidKeyException; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 

import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.SecretKey; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 

import android.util.Base64; 
import android.util.Log; 

public class Crypto { 
    public static final String TAG = "smsfwd"; 

     private static Cipher aesCipher; 
     private static SecretKey secretKey; 
     private static IvParameterSpec ivParameterSpec; 

     private static String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding"; 
     private static String CIPHER_ALGORITHM = "AES"; 
     // Replace me with a 16-byte key, share between Java and C# 
     private static byte[] rawSecretKey = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 

     private static String MESSAGEDIGEST_ALGORITHM = "MD5"; 

     public Crypto(String passphrase) { 
      byte[] passwordKey = encodeDigest(passphrase); 

      try { 
       aesCipher = Cipher.getInstance(CIPHER_TRANSFORMATION); 
      } catch (NoSuchAlgorithmException e) { 
       Log.e(TAG, "No such algorithm " + CIPHER_ALGORITHM, e); 
      } catch (NoSuchPaddingException e) { 
       Log.e(TAG, "No such padding PKCS5", e); 
      } 

      secretKey = new SecretKeySpec(passwordKey, CIPHER_ALGORITHM); 
      ivParameterSpec = new IvParameterSpec(rawSecretKey); 
     } 

     public String encryptAsBase64(byte[] clearData) { 
      byte[] encryptedData = encrypt(clearData); 
      return Base64.encodeToString(encryptedData, Base64.DEFAULT); 
     } 

     public byte[] encrypt(byte[] clearData) { 
      try { 
       aesCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec); 
      } catch (InvalidKeyException e) { 
       Log.e(TAG, "Invalid key", e); 
       return null; 
      } catch (InvalidAlgorithmParameterException e) { 
       Log.e(TAG, "Invalid algorithm " + CIPHER_ALGORITHM, e); 
       return null; 
      } 

      byte[] encryptedData; 
      try { 
       encryptedData = aesCipher.doFinal(clearData); 
      } catch (IllegalBlockSizeException e) { 
       Log.e(TAG, "Illegal block size", e); 
       return null; 
      } catch (BadPaddingException e) { 
       Log.e(TAG, "Bad padding", e); 
       return null; 
      } 
      return encryptedData; 
     } 

     private byte[] encodeDigest(String text) { 
      MessageDigest digest; 
      try { 
       digest = MessageDigest.getInstance(MESSAGEDIGEST_ALGORITHM); 
       return digest.digest(text.getBytes()); 
      } catch (NoSuchAlgorithmException e) { 
       Log.e(TAG, "No such algorithm " + MESSAGEDIGEST_ALGORITHM, e); 
      } 

      return null; 
     } 
} 

MainActivity :

public void clck(View v) { 
     try { 

      Crypto crpt = new Crypto("MyDifficultPassw"); 
      System.out.println(crpt.encryptAsBase64("tryToEncrypt".getBytes())); 

     } catch (Exception e) { 
      System.out.println(e.toString()); 
     } 

    } 

outpıt했다 : 2xrT + 9gHAw4Nh9H57kluwQ의 == ASP.Net 측 :

protected void Page_Load(object sender, EventArgs e) 
     { 
       Crypto crp = new Crypto("MyDifficultPassw"); 
       string asd = crp.DecryptFromBase64("2xrT+9gHAw4Nh9H57kluwQ=="); 
     } 

     public class Crypto 
     { 
      private ICryptoTransform rijndaelDecryptor; 
      // Replace me with a 16-byte key, share between Java and C# 
      private static byte[] rawSecretKey = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 

      public Crypto(string passphrase) 
      { 
       byte[] passwordKey = encodeDigest(passphrase); 
       RijndaelManaged rijndael = new RijndaelManaged(); 
       rijndaelDecryptor = rijndael.CreateDecryptor(passwordKey, rawSecretKey); 
      } 

      public string Decrypt(byte[] encryptedData) 
      { 
       byte[] newClearData = rijndaelDecryptor.TransformFinalBlock(encryptedData, 0, encryptedData.Length); 
       return Encoding.ASCII.GetString(newClearData); 
      } 

      public string DecryptFromBase64(string encryptedBase64) 
      { 
       return Decrypt(Convert.FromBase64String(encryptedBase64)); 
      } 

      private byte[] encodeDigest(string text) 
      { 
       MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider(); 
       byte[] data = Encoding.ASCII.GetBytes(text); 
       return x.ComputeHash(data); 
      } 
     } 

     static string DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key 
, byte[] IV) 
     { 
      // Check arguments. 
      if (cipherText == null || cipherText.Length <= 0) 
       throw new ArgumentNullException("cipherText"); 
      if (Key == null || Key.Length <= 0) 
       throw new ArgumentNullException("Key"); 
      if (IV == null || IV.Length <= 0) 
       throw new ArgumentNullException("Key"); 

      // Declare the string used to hold 
      // the decrypted text. 
      string plaintext = null; 

      // Create an Aes object 
      // with the specified key and IV. 
      using (Aes aesAlg = Aes.Create()) 
      { 
       aesAlg.Key = Key; 
       aesAlg.IV = IV; 
       aesAlg.Padding = PaddingMode.None; 

       // Create a decrytor to perform the stream transform. 
       ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key 
, aesAlg.IV); 



       // Create the streams used for decryption. 
       using (MemoryStream msDecrypt = new MemoryStream(cipherText)) 
       { 

        using (CryptoStream csDecrypt = new CryptoStream(msDecrypt 
, decryptor, CryptoStreamMode.Read)) 
        { 

         using (StreamReader srDecrypt = new StreamReader(
csDecrypt)) 
         { 

          // Read the decrypted bytes from the decrypting 

          // and place them in a string. 
          plaintext = srDecrypt.ReadToEnd(); 
         } 
        } 
       } 

      } 

      return plaintext; 

     } 
관련 문제