Продолжайте получать javax.crypto.IllegalBlockSizeException: длина ввода должна быть кратна 16 при дешифровании с использованием дополненного шифра - PullRequest
1 голос
/ 26 февраля 2020

При кодировании алгоритма AES-192 в java между сокетами я получаю это исключение и не вижу, как его исправить. Я думаю, что это должно быть что-то с тем, как он декодирует сервер, как я читал в другом посте, но я не могу понять это правильно. Моя java версия 13 в случае необходимости. Спасибо за помощь 1008 *

КОД КЛИЕНТА

import java.net.*; 
import java.io.*; 
import javax.crypto.*;
import java.security.*;
import java.util.*;
import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Base64;



public class Alice { 
    private Socket socket = null; 
    private DataOutputStream out = null; 
    private BufferedReader in = null; 


    public Alice(String address, int port)  { 
        try { 
            socket = new Socket(address, port);              
            in = new BufferedReader(new InputStreamReader(System.in));

            out = new DataOutputStream(socket.getOutputStream()); 
        } catch(UnknownHostException u) { 
            System.out.println(u); 
        } catch(IOException i) { 
            System.out.println(i); 
        }   
        String plaintext = "";

        while(!plaintext.equals("Stop")){
            try { 
                System.out.println("Introduce plaintext:");
                plaintext = in.readLine(); 

                String ciphertext = encrypt(plaintext);

                System.out.println("Encrypted: " + ciphertext + "\n");
                out.writeUTF(ciphertext); 
            }  catch(IOException i) { 
                System.out.println(i); 
            } 
        }

        try {
            socket.close();
            in.close();
            out.close();
        } catch(IOException i) {
            System.out.println(i);
        }
    }


    public static String encrypt(String value) {
        try {
            String key = "i5q5jZFd73kuK3wG2jTCvtWp";
            SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

            int ivSize = 16;
            byte[] iv = new byte[ivSize];
            SecureRandom random = new SecureRandom();
            random.nextBytes(iv);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);        

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);

            byte[] encrypted = cipher.doFinal(value.getBytes());

            byte[] encryptedAndIV = new byte[ivSize + encrypted.length];
            System.arraycopy(iv, 0, encryptedAndIV, 0, ivSize);
            System.arraycopy(encrypted, 0, encryptedAndIV, ivSize, encrypted.length);

            return new String(Base64.getEncoder().encode(encryptedAndIV));
        } catch (Exception e) {
            throw new RuntimeException("Error occured while encrypting data", e); 
        }
    }


    public static void main(String args[])  { 
        Alice alice = new Alice("localhost", 3125); 
    } 
}

1 Ответ

0 голосов
/ 27 февраля 2020

Ваша проблема в ваших процедурах расшифровки. Обычно в CB C вы должны следовать

Encryption;

  • Шифровать сообщение и возвращать байты
  • перед IV в массив байтов большего размера с size=IV.lenght+encrypted.lenght
  • добавьте зашифрованные байты в более крупные байты, скопировав IV||encrypted
  • Кодирование байтов в base64 (или аналогичное) base64(IV||encrypted)
  • Отправка сообщения

Расшифровка;

  • Получить сообщение
  • Декодировать сообщение в байты из base64
  • извлечь IV из начала байтов
  • извлечение зашифрованных байтов из байтов
  • Шифрование байтов для получения сообщения

В вашем коде вы не декодировали байты перед расшифровкой для извлечения IV, вы сделали это во время расшифровки.

ByteBuffer buffer = ByteBuffer.wrap(new Base64().decode(encryptedText));

//get the IV from the bytes
byte[] iv = new byte[ivSize];
buffer.get(iv, 0, iv.length);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);

//get the encrypted bytes
byte[] encryptedTextBytes = new byte[buffer.capacity() - iv.length];
buffer.get(encryptedTextBytes);

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameterSpec);

byte[] original = cipher.doFinal(encryptedTextBytes);
...