Расшифровка зашифрованного текста .net в Java

Я пытаюсь расшифровать строку, зашифрованную в C# (.Net), используя тот же ключ, но получаю Excpetion, как показано ниже.

Код C#

 //Decrypting a string
String key = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
                //Encrypting a string
        public static string passwordEncrypt(string inText, string key)
        {
            byte[] bytesBuff = Encoding.Unicode.GetBytes(inText);
            using (Aes aes = Aes.Create())
            {
                Rfc2898DeriveBytes crypto = new Rfc2898DeriveBytes(key, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
                aes.Key = crypto.GetBytes(32);
                aes.IV = crypto.GetBytes(16);
                using (MemoryStream mStream = new MemoryStream())
                {
                    using (CryptoStream cStream = new CryptoStream(mStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cStream.Write(bytesBuff, 0, bytesBuff.Length);
                        cStream.Close();
                    }
                    inText = Convert.ToBase64String(mStream.ToArray());
                }
            }
            return inText;
        }

Код Java

final static String key = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

final static byte[] ivBytes = new byte[] { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00 };
public static String decryptData(String base64Text) {
        String plainText = "";
        try {
            byte[] keyBytes = key.getBytes("UTF-8");
            try {
                // byte[] cipherData = decrypt(ivBytes, keyBytes,
                // Base64.decode(base64Text.getBytes("UTF-8"), Base64.DEFAULT));
                byte[] cipherData = decrypt(ivBytes, keyBytes,
                        Base64.getDecoder().decode(base64Text.getBytes("UTF-8")));
                plainText = new String(cipherData, "UTF-8");
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (InvalidAlgorithmParameterException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return plainText;
    }

Я получаю исключение:

java.security.InvalidKeyException: Invalid AES key length: 36 bytes
    at com.sun.crypto.provider.AESCrypt.init(AESCrypt.java:87)
    at com.sun.crypto.provider.CipherBlockChaining.init(CipherBlockChaining.java:95)
    at com.sun.crypto.provider.CipherCore.init(CipherCore.java:591)
    at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:346)
    at javax.crypto.Cipher.implInit(Cipher.java:809)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:867)
    at javax.crypto.Cipher.init(Cipher.java:1399)
    at javax.crypto.Cipher.init(Cipher.java:1330)
    at com.trinity.report.loginAuth.AES256Cipher.encrypt(AES256Cipher.java:27)
    at com.trinity.report.loginAuth.AES256Cipher.encryptData(AES256Cipher.java:52)
    at com.trinity.report.loginAuth.AES256Cipher.main(AES256Cipher.java:107)

Тот же ключ используется для шифрования.

Sample Key: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ

Encrypted String: zSdnqGp9B1BjMsvzvAeYvEidAgUrI%2ByrOGf%2BGVn9tzo%3D

Plain Text: testthree

Пожалуйста помоги. Заранее спасибо.

Ну, AES поддерживает 128, 192 и 256-битные ключи, который составляет 16, 24 или 32 байта. Ваш ключ имеет длину 36 байтов, поэтому он недействителен. Цитата из введения Технические характеристики: «Этот стандарт определяет алгоритм Rijndael, симметричный блочный шифр, который может обрабатывать блоки данных длиной 128 бит, с использованием ключей шифрования длиной 128, 192 и 256 бит.» (выделено мной)

Thomas 01.04.2021 12:19

В коде .NET вы берете свой ключ и преобразуете его через Rfc2898DeriveBytes, чтобы получить ключ (32 байта) и IV. Но в коде Java вы используете свой ключ и iV напрямую (а первый имеет неправильную длину). Начните без Rfc2898DeriveBytes, просто установите фиксированный ключ нужной длины в обоих случаях.

Richard 01.04.2021 12:22

В отношении кода C# (который отличается от кода расшифровки Java): установка значения IV, полученного из пароля, не кажется хорошей идеей, поскольку оно будет одинаковым каждый раз для одного и того же пароля. См. Комментарий к AES-CBC с возобновленным IV здесь.

Llama 01.04.2021 12:25
Rfc2898DeriveBytes реализует PBKDF2, используя HMACSHA1 по умолчанию. В Java это соответствует PBKDF2WithHmacSHA1, см. здесь. При этом ключ и IV должны быть производными от пароля (key) и соли (0x49, 0x76 ...). Обратите внимание, что статическая соль (как в коде C#) небезопасна.
Topaco 01.04.2021 12:34
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
4
64
0

Другие вопросы по теме