首页 > 解决方案 > Android 中的 Java 和 .Net AES 256 加密结果不匹配。在 .Net 中因“填充无效且无法删除”而失败

问题描述

任何人都可以在下面的代码中提供帮助,我正在尝试在 Android 中实现AES Encryption ,但 android 生成的代码与服务器端 .Net AES Encryption不匹配。请找到下面的代码让我知道出了什么问题:

.Net 代码

    private string GetEncryptedData(string clearText)

    {
       string EncryptionKey = "password";
        byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(clearBytes, 0, clearBytes.Length);
                    cs.Close();
                }
                clearText = System.Web.HttpContext.Current.Server.UrlEncode(Convert.ToBase64String(ms.ToArray()));
            }
        }
        return clearText;
    }

Android 中的 Java 代码:

    private static String secretKey1 = "password";
    private static String salt = "ssshhhhhhhhhhh!!!!";

    public static String encrypt(String strToEncrypt, String secret)

    {
        try
        {
            byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            IvParameterSpec ivspec = new IvParameterSpec(iv);

            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
            KeySpec spec = new PBEKeySpec(secret.toCharArray(), salt.getBytes(), 65536, 256);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
            //Log.d("qwqwqwqw1",secretKey.toString());

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);
            //return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));

            return URLEncoder.encode(Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))), "UTF-8");
        }
        catch (Exception e)
        {
            System.out.println("Error while encrypting: " + e.toString());
        }
        return null;
    }

.Net 加密结果:

%2bJnjgtiCX9VSxwTU22jCJluBxh%2bkFxVlfBasAorRO%2fo%3d

Java加密结果

PwoZePSM%2BjoyPubZr780Fg%3D%3D

我试图改变这一点

byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
to byte[] iv = { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 }

在 JAVA 代码中仍然出现错误“预期 IV 长度为 16 但为 13”

谁能告诉这有什么问题。

更新:现在我正在使用它。请让我知道出了什么问题:

代码:

byte[] salt1 =  new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76};

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec pbeKeySpec = new PBEKeySpec(strToEncrypt.toCharArray(), salt1, 1000, 384);
byte[] derivedData = factory.generateSecret(pbeKeySpec).getEncoded();
byte[] key = new byte[32];
byte[] iv = new byte[16];
System.arraycopy(derivedData, 0, key, 0, key.length);
System.arraycopy(derivedData, key.length, iv, 0, iv.length);

SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
//return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
//byte[] result = cipher.doFinal(Base64.getEncoder().decode(strToEncrypt));

String value = Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes(StandardCharsets.UTF_16LE)));
String result1 = URLEncoder.encode(value,"UTF_16LE");

标签: javac#android.netkotlin

解决方案


推荐阅读