Android AES加密从C#到Java

Android AES加密从C#到Java,java,c#,android,encryption,aes,Java,C#,Android,Encryption,Aes,我正在将我的C#加密代码转换为Android 我面临的问题是,我无法像C#一样加密文本。 下面我复制粘贴两个代码 两者都是关于使用它的工作代码。你可以使用任何密码和任何纯文本。你会发现两者都有不同的输出 C#代码 System.security.Cryptography.RijndaelManaged AES = new System.Security.Cryptography.RijndaelManaged(); System.Security.Cryptography.MD5CryptoSe

我正在将我的C#加密代码转换为Android

我面临的问题是,我无法像C#一样加密文本。 下面我复制粘贴两个代码

两者都是关于使用它的工作代码。你可以使用任何密码和任何纯文本。你会发现两者都有不同的输出

C#代码

System.security.Cryptography.RijndaelManaged AES = new System.Security.Cryptography.RijndaelManaged();
System.Security.Cryptography.MD5CryptoServiceProvider Hash_AES = new System.Security.Cryptography.MD5CryptoServiceProvider();

final MessageDigest Hash_AES = MessageDigest.getInstance("MD5");

        String encrypted = "";
        try {
            byte[] hash = new byte[32];
            byte[] temp = Hash_AES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(pass));
            final byte[] temp = Hash_AES.digest(pass.getBytes("US-ASCII"));

            Array.Copy(temp, 0, hash, 0, 16);
            Array.Copy(temp, 0, hash, 15, 16);
            AES.Key = hash;
            AES.Mode = System.Security.Cryptography.CipherMode.ECB;
            System.Security.Cryptography.ICryptoTransform DESEncrypter = AES.CreateEncryptor();
            byte[] Buffer = System.Text.ASCIIEncoding.ASCII.GetBytes(input);
            encrypted = Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length));
        } catch (Exception ex) {

        }
        return encrypted;
private static String TRANSFORMATION = "AES/ECB/NoPadding";
private static String ALGORITHM = "AES";
private static String DIGEST = "MD5";
byte[] encryptedData;

public RijndaelCrypt(String password,String plainText) {

    try {

        //Encode digest
        MessageDigest digest;           
        digest = MessageDigest.getInstance(DIGEST);            
        _password = new SecretKeySpec(digest.digest(password.getBytes()), ALGORITHM);

        //Initialize objects
        _cipher = Cipher.getInstance(TRANSFORMATION);

       _cipher.init(Cipher.ENCRYPT_MODE, _password);
        encryptedData = _cipher.doFinal(text);

    } catch (InvalidKeyException e) {
        Log.e(TAG, "Invalid key  (invalid encoding, wrong length, uninitialized, etc).", e);
        return null;
    } catch (InvalidAlgorithmParameterException e) {
        Log.e(TAG, "Invalid or inappropriate algorithm parameters for " + ALGORITHM, e);
        return null;
    } catch (IllegalBlockSizeException e) {
        Log.e(TAG, "The length of data provided to a block cipher is incorrect", e);
        return null;
    } catch (BadPaddingException e) {
        Log.e(TAG, "The input data but the data is not padded properly.", e);
        return null;
    }               

    return Base64.encodeToString(encryptedData,Base64.DEFAULT);
}
这是我的Android java代码

ANDROID JAVA代码

System.security.Cryptography.RijndaelManaged AES = new System.Security.Cryptography.RijndaelManaged();
System.Security.Cryptography.MD5CryptoServiceProvider Hash_AES = new System.Security.Cryptography.MD5CryptoServiceProvider();

final MessageDigest Hash_AES = MessageDigest.getInstance("MD5");

        String encrypted = "";
        try {
            byte[] hash = new byte[32];
            byte[] temp = Hash_AES.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(pass));
            final byte[] temp = Hash_AES.digest(pass.getBytes("US-ASCII"));

            Array.Copy(temp, 0, hash, 0, 16);
            Array.Copy(temp, 0, hash, 15, 16);
            AES.Key = hash;
            AES.Mode = System.Security.Cryptography.CipherMode.ECB;
            System.Security.Cryptography.ICryptoTransform DESEncrypter = AES.CreateEncryptor();
            byte[] Buffer = System.Text.ASCIIEncoding.ASCII.GetBytes(input);
            encrypted = Convert.ToBase64String(DESEncrypter.TransformFinalBlock(Buffer, 0, Buffer.Length));
        } catch (Exception ex) {

        }
        return encrypted;
private static String TRANSFORMATION = "AES/ECB/NoPadding";
private static String ALGORITHM = "AES";
private static String DIGEST = "MD5";
byte[] encryptedData;

public RijndaelCrypt(String password,String plainText) {

    try {

        //Encode digest
        MessageDigest digest;           
        digest = MessageDigest.getInstance(DIGEST);            
        _password = new SecretKeySpec(digest.digest(password.getBytes()), ALGORITHM);

        //Initialize objects
        _cipher = Cipher.getInstance(TRANSFORMATION);

       _cipher.init(Cipher.ENCRYPT_MODE, _password);
        encryptedData = _cipher.doFinal(text);

    } catch (InvalidKeyException e) {
        Log.e(TAG, "Invalid key  (invalid encoding, wrong length, uninitialized, etc).", e);
        return null;
    } catch (InvalidAlgorithmParameterException e) {
        Log.e(TAG, "Invalid or inappropriate algorithm parameters for " + ALGORITHM, e);
        return null;
    } catch (IllegalBlockSizeException e) {
        Log.e(TAG, "The length of data provided to a block cipher is incorrect", e);
        return null;
    } catch (BadPaddingException e) {
        Log.e(TAG, "The input data but the data is not padded properly.", e);
        return null;
    }               

    return Base64.encodeToString(encryptedData,Base64.DEFAULT);
}
我应该在pass中使用“US-ASCII”还是需要它

  • 使用相同的操作模式:ECB或CBC
  • 使用相同的字符集:最好坚持使用“UTF-8”
  • 使用相同的密钥:在C代码中,您将128位密钥加倍为256位
当将CBC与随机IV一起使用时,预期相同的明文的密文不同。解密是决定您是否成功的操作

请注意,ECB在语义上是不安全的。将CBC与随机IV一起使用。IV不必是秘密的,因此您可以将其预先添加到密文中,并在解密之前将其切掉


最好使用像GCM或EAX这样的身份验证模式,或者如果没有提供加密然后MAC方案。您自己很难正确地实现它,所以请坚持使用一些为您这样做的库,如RNCryptor。

我认为您需要在Java代码的getBytes()方法中传递“US-ASCII”编码方案。传递一个字符集方案总是一个很好的做法。@Artojom谢谢你的建议。在我删除了random IV。但是我发现密码给了我错误的值。你知道哪里出了问题吗?你应该用同一把钥匙。我延长了我的回答。