Мой CipherOutputStream молча терпит неудачу - PullRequest
4 голосов
/ 08 февраля 2010

Я пытаюсь зашифровать некоторые двоичные данные в Java с помощью открытого ключа, как описано на этой полезной странице: http://www.junkheap.net/content/public_key_encryption_java

По указанию страницы я создал открытый и закрытый ключи с помощью команд:

openssl genrsa -aes256 -out private.pem 2048
openssl rsa -in private.pem -pubout -outform DER -out public.der

Теперь я сохраняю зашифрованные данные с помощью небольшой программы:

public class Rsa {

    public static void main(String[] args) throws Exception, IOException {
        File keyFile = new File("public.der");
        byte[] encodedKey = new byte[(int) keyFile.length()];

        new FileInputStream(keyFile).read(encodedKey);

        X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);

        KeyFactory kf = KeyFactory.getInstance("RSA");
        PublicKey pk = kf.generatePublic(publicKeySpec);

        Cipher rsa = Cipher.getInstance("RSA");

        rsa.init(Cipher.ENCRYPT_MODE, pk);

        FileOutputStream fileOutputStream = new FileOutputStream(
                "encrypted.rsa");
        OutputStream os = new CipherOutputStream(fileOutputStream, rsa);

        byte[] raw = new byte[245];
        raw[0] = 4;

        os.write(raw);
        os.flush();
        os.close();


    }
}

Приведенный выше код работает, но когда я изменяю размер байтового массива на 246, он создает файл нулевой длины!

Что я делаю не так?

1 Ответ

5 голосов
/ 08 февраля 2010

CipherOutputStream имеет тенденцию поглощать исключения, сгенерированные объектами Cipher и OutputStream, которые он переносит. Реализация Sun RSA не будет шифровать больше, чем M-11 байтов, где M - длина в байтах модуля. Это верно для PKCS1Padding по умолчанию, который вы всегда должны использовать, если вы действительно не знаете, что делаете. Вы можете указать NoPadding и, таким образом, получить полные байты M.

RSA не является правильным выбором для шифрования больших объемов данных. Общепринятый метод шифрования данных с помощью RSA заключается в генерации случайного симметричного сеансового ключа K. например ключ AES, зашифруйте данные симметричным алгоритмом с помощью K, затем зашифруйте K, используя ключи RSA всех получателей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...