Java AES 256 Decrypt не расшифровывает первые 16 байтов - PullRequest
0 голосов
/ 28 ноября 2018

Проблема: приведенный ниже код, кажется, правильно шифрует AES 256, но при расшифровке первые 16 байтов являются нечитаемыми «байтами», либо не дешифрованы, либо другими.Текст после первых 16 байтов корректно дешифруется.


Я видел много публикаций по этой проблеме, где, когда вы дешифруете AES 256, первые 16 байтов все еще, ну, байты не текстовые.Здесь я попробовал такие вещи, как объединение байтов IV с зашифрованными байтами перед Base64Encodeing, но это не сработало.Я также убедился, что два моих веб-метода (шифрование и дешифрование) используют одни и те же байты IV.

Моя отдельная логика (Java-приложение) работает должным образом.После многих головокружительных часов поисков и проб, я хотел бы спросить некоторых экспертов здесь.

Буду признателен за любые предположения относительно того, что может быть не так с кодом ниже.

Ниже приведены два метода GET для веб-служб: один для шифрования, а другой для дешифрования.

Заранее спасибо,

get("/AESEncrypt/:stringToEncrypt/:Base64SecretKey", (request, response) ->
        {
            String myKey = request.params("secretKey");
            byte[]  ivBytes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

            // assume encoded since string could be any characters
            String str2Encrypt = URLDecoder.decode(request.params("stringToEncrypt"), "UTF-8");

            //Salt please.
            String salt = "somesalt";
            final byte[] saltBytes = salt.getBytes("UTF-8");

            // Use SHA 256.
            final SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
            final PBEKeySpec spec = new PBEKeySpec(
                    myKey.toCharArray(),
                    saltBytes,
                    65536,
                    256);

            final SecretKey secretKey = factory.generateSecret(spec);
            final SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

            //encrypt the message
            final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secret);
            final AlgorithmParameters params = cipher.getParameters();

            final byte[] encryptedTextBytes = cipher.doFinal(str2Encrypt.getBytes("UTF-8"));
            return Base64.encodeBase64String(encryptedTextBytes);
        });

        //-----------

        get("/AESDecrypt/:stringToDecrypt/:decryptKey", (request, response) ->
        {
            String base64Key = request.params("decryptKey");
            String strToDecrypt =request.params("stringToDecrypt");
            String decryptedString = null;

            //Salt please.
            String salt = "somesalt";
            final byte[] saltBytes = salt.getBytes("UTF-8");

            // Derive the key
            final SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
            final PBEKeySpec spec = new PBEKeySpec(
                    base64Key.toCharArray(),
                    saltBytes,
                    65536,
                    256
            );
            final SecretKey secretKey = factory.generateSecret(spec);
            final SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");

            // Decrypt the message
            final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

            final AlgorithmParameters params = cipher.getParameters();
           // byte[] ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
            byte[] ivBytes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

            cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes));
            byte[] decryptedTextBytes = null;
            try
            {
                decryptedTextBytes = cipher.doFinal(Base64.decodeBase64(strToDecrypt));
            }
            catch (IllegalBlockSizeException e)
            {
                e.printStackTrace();
            }
            catch (BadPaddingException e)
            {
                e.printStackTrace();
            }

            return new String(decryptedTextBytes);
        });

1 Ответ

0 голосов
/ 28 ноября 2018

Вы передаете IV во время расшифровки, но вы не передаете его во время шифрования.Таким образом, IV является случайным, что приводит к повреждению первого блока при дешифровании (потому что вы используете другой IV).Вы имели в виду следующее:

cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(ivBytes));

Обратите внимание, что шифрование нескольких сообщений одним и тем же ключом и IV небезопасно.Вы действительно хотите случайный IV, а не фиксированный.Но в любом случае вы должны использовать один и тот же.

...