Расшифровка «длинного» сообщения, зашифрованное RSA Java

StackOverflow https://stackoverflow.com/questions/2653591

Вопрос

Привет, это тот же вопрос, что было задано два года назад:Java / JCE: расшифровка «длинного» сообщения, зашифрованное RSA

У меня был большой байтовый массив и RSA keypair, инициированный значением 1024. Использование шифрования RSA и указанный размер ключа является сильным требованием, я не могу его изменить. Поэтому я не могу использовать симметричное шифрование с симметричным ключом асимметричного шифрования. Я не могу использовать какие-либо другие ключи. У меня был байтовый массив и нуждается в зашифрованном байтовом массиве, который будет возвращен. Интересно, есть ли какой-нибудь готовый инструмент, который может управлять с этой проблемой?

Извините за такой любимый вопрос, но мне действительно нужна помощь.

Это было полезно?

Решение

Как указано, ваш вопрос имеет один ответ, и это «нет». Encryption RSA является алгоритмом, который шифрует сообщения до данного размера, который зависит от размера ключа; с 1024-битным ключом RSA и RSA как стандарт Описывает его максимальный размер 117 байт, не более. Нет никакого способа зашифровать более широкое сообщение с RSA, и это определенно, математическая уверенность.

Если вам действительно нужно обработать более длинные сообщения, то вы обязательно должны добавить что-то еще. В этом случае, пожалуйста, пожалуйста, Не пытайтесь сделать что-нибудь признам к своему собственным разрабатывающим с каким-то ОН-Умным расщеплением данных в небольшие блоки и тому подобное. Этот путь приводит к гибели. Вы можете произвести что-то, что появляется Чтобы составить и пробежать, но каким-то образом будет неизменно слабым, вроде почти все другие домашние вариации на криптографию. Это потому, что безопасность не может быть проверена: это не случай «работает» или «не работает».

Хорошо тростный путь асимметричного шифрования идет таким образом:

  1. Вы выбираете случайную последовательность байтов некоторой подходящей длины, например, 128 битов (это 16 байтов). Давайте назовем это K..
  2. Вы шифруете K. с открытым ключом RSA; Это урожайность Свидетельствовать.
  3. Вы шифруете сообщение с K. используя симметричный алгоритм шифрования ("AES/CBC/PKCS5Padding"). Поскольку это ключ с одним выстрелом, вы можете использовать All-Zeros IV. Это дает кучу байтов, давайте назовем это F..
  4. Зашифрованное сообщение - тогда конкатенация Свидетельствовать и F..

Расшифровка выходит в обратном порядке: закрытый ключ RSA используется для восстановления K. от Свидетельствовать, потом K. используется для расшифровки F. в исходное сообщение. Ключ K. никогда не хранится нигде, а Новый ключ К. генерируется каждый раз (даже если вы зашифруете одно и то же сообщение дважды). Это важно, не меняйте, если вы не понимаете, что вы делаете (и если вы сделаете, то вы уже знаете это).

Учитывая то, что вы говорите о вашей проблеме, вы имеют сделать что-то еще, чем «просто RSA». Процедура, которую я опишу выше, это о лучшем «что-то другом», что вы могли бы придумать, Безопасность.

Сборка некоторых криптографических элементов в такой протокол - это процесс, чревающий подводными камнями, поэтому вам может возникнуть удача с использованием уже определенного формата и библиотеки поддержки. Две общие форматы для асимметричного шифрования CMS. и OpenPGP.. Отказ Библиотека, которая поддерживает как и имеет хорошую репутацию, Надувной замок.

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

Если вам нужно зашифровать / расшифровать длинные строки с использованием RSA, то вы можете нарушить байты в меньших «кусках» и обрабатывать каждый кусок байтов через шифр по одному во время хранения результатов в байтбуфере.

Шифрование:

byte[] encData = null;
try {

    // create public key
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(key);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PublicKey pk = kf.generatePublic(publicKeySpec);

    Cipher pkCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    pkCipher.init(Cipher.ENCRYPT_MODE, pk);

    int chunkSize = 117; // 1024 / 8 - 11(padding) = 117
    int encSize = (int) (Math.ceil(data.length/117.0)*128);
    int idx = 0;
    ByteBuffer buf = ByteBuffer.allocate(encSize);
    while (idx < data.length) {
        int len = Math.min(data.length-idx, chunkSize);
        byte[] encChunk = pkCipher.doFinal(data, idx, len);
        buf.put(encChunk);
        idx += len;
    }

    // fully encrypted data     
    encData = buf.array();
} catch (Exception e) {
    e.printStackTrace();

Дешифрование

Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsaCipher.init(Cipher.DECRYPT_MODE, rsaPk);

int chunkSize = 128;
int idx = 0;
ByteBuffer buf = ByteBuffer.allocate(data.length);
while(idx < data.length) {
    int len = Math.min(data.length-idx, chunkSize);
    byte[] chunk = rsaCipher.doFinal(data, idx, len);
    buf.put(chunk);
    idx += len;
}

// fully decrypted data
byte[] decryptedData = buf.array();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top