Почему зашифрованные байты RSA в Java различаются? - PullRequest
1 голос
/ 12 марта 2020

Я пытаюсь кодировать гибридное шифрование для связи между сервером и клиентом. Таким образом, я отправляю открытый ключ c RSA от клиента, сервер шифрует его ключ AES и отправляет его обратно. Но потом, если я расшифрую его на клиентском сайте, ключ будет длиннее, чем я его отправлю, и я не знаю почему ...

Вот код:

Клиент:

socket.getOutputStream().write(security.getKeyPair().getPublic().getEncoded());
byte[] keyBuffer = new byte[512];
socket.getInputStream().read(keyBuffer);
security.setKey(new SecretKeySpec(security.decryptRSA(keyBuffer).getBytes(), "AES"));

Сервер:

byte[] keyBuffer = new byte[550];
this.socket.getInputStream().read(keyBuffer);
PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(keyBuffer));
this.socket.getOutputStream().write(this.security.encryptRSA(this.security.getKey().getEncoded(), publicKey));

Методы класса безопасности:

public byte[] encryptRSA(byte[] message, PublicKey key) {
        byte[] buffer = message;
        try {
            this.cipher = Cipher.getInstance("RSA");
            this.cipher.init(Cipher.ENCRYPT_MODE, key);
            buffer = this.cipher.doFinal(buffer);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            e.printStackTrace();
        }

        return buffer;
    }


public String decryptRSA(byte[] message) {
        byte[] buffer = message;
        try {
            this.cipher = Cipher.getInstance("RSA");
            this.cipher.init(Cipher.DECRYPT_MODE, this.keyPair.getPrivate());
            buffer = this.cipher.doFinal(buffer);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            e.printStackTrace();
        }

        return new String(buffer);
    }


Спасибо!

1 Ответ

3 голосов
/ 13 марта 2020

Вероятно, проблема заключается в том, что вы кодировали свой код без необходимости:

   return new String(buffer);

Это будет интерпретировать буфер определенным образом как строку. Однако ключ состоит из случайных байтов, которые могут декодироваться до непредвиденных символов. Затем вы возвращаетесь обратно в байты, используя .getBytes(), но к тому времени уже слишком поздно.

Просто оставьте ключ AES в байтах, и эта часть должна быть исправлена.


Кроме того read - это не то же самое, что readNBytes​ (и просто read неверно), но это, вероятно, не ошибка; у вас возникнут проблемы с RSA, а не с ключом AES, если это будет проблемой.


Обратите внимание, что вы можете получить размер модуля в байтах, чтобы определить количество байтов для чтения, так что вы там также не нужно иметь константу 512 (которую я бы написал как KEY_SIZE / Byte.SIZE, где KEY_SIZE = 4096, чтобы хотя бы указать, что буфер точно соответствует размеру ключа.

...