Как зашифровать InputStream с помощью JNCryptor

Я разрабатываю приложение для iPad и использую RNCryptor для шифрования и дешифрования на устройстве. Существует Java-версия этого формата шифрования, доступная в виде JNCryptor.

Теперь у меня есть данные для чтения из InputStream, но я хочу зашифровать данные перед их чтением. Я нашел класс под названием CipherInputStream, который, кажется, делает именно то, что я ищу. Единственное, мне нужен шифрProvider), чтобы указать метод шифрования, и я не знаю, как это сделать. Можно ли вообще определить собственного провайдера?

Есть ли у кого-нибудь предложения по альтернативным способам использования JNCryptor для шифрования InputStream?


person Johanneke    schedule 09.04.2013    source источник
comment
Я так и сделаю, спасибо :) На данный момент я написал свой собственный код, но было бы неплохо, если бы был метод обновления, который я мог бы вызывать, вместо того, чтобы делать все подряд. Я думаю, что единственный метод из библиотеки, который я могу использовать сейчас, — это генерация ключей, ха-ха. Я разместил свое решение в ответе на этот вопрос, возможно, вы сможете его использовать :)   -  person Johanneke    schedule 16.04.2013


Ответы (3)


В конце концов я написал класс для чтения InputStream, шифрования частей данных за раз и записи в PipedOutputStream. Этот PipedOutputStream я затем подключил к PipedInputStream, который я в конце концов вернул. Шифрование и запись в PipedOutputStream происходят в отдельном потоке, чтобы избежать взаимоблокировки.

PipedInputStream pin = new PipedInputStream();
PipedOutputStream pout = new PipedOutputStream(pin);
EncryptionPipe pipe = new EncryptionPipe(5, pout, in, cipher, mac, metaData);
//EncryptionPipe(int interval, OutputStream out, InputStream in
//              ,Cipher cipher, Mac mac, byte[] metaData)
pipe.start();
return pin;

И в EncryptionPipe:

public class EncryptionPipe extends Thread {
    ...
    @Override
    public void run() {
        try {
            mac.update(metaData);
            out.write(metaData);

            byte[] buf = new byte[1024];
            int bytesRead = 0;
            byte[] crypted;
            byte[] hmac;
            while ((bytesRead = in.read(buf)) != -1) {
                if (bytesRead < buf.length) {
                    //the doFinal methods add padding if necessary, important detail!
                    crypted = cipher.doFinal(buf, 0, bytesRead);
                    hmac = mac.doFinal(crypted);

                    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
                    bytes.write(crypted);
                    bytes.write(hmac);
                    crypted = bytes.toByteArray();
                    bytesRead = crypted.length;
                    bytes.close();
                } else {
                    crypted = cipher.update(buf, 0, bytesRead);
                    mac.update(crypted, 0, bytesRead);
                }
                out.write(crypted, 0, bytesRead);
                synchronized (this) {
                    this.wait(interval);
                }
            }
            out.close();
            ...
        }
    }
}
person Johanneke    schedule 16.04.2013

JNCryptor v1.1.0 был выпущен вчера и обеспечивает поддержку потокового шифрования и дешифрования.

Используйте AES256JNCryptorInputStream для расшифровки и AES256JNCryptorOutputStream для шифрования.

person Duncan Jones    schedule 24.08.2014

Вы можете использовать поставщика Java по умолчанию. Чтобы создать экземпляр шифра, вы должны использовать

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")

При этом используются AES и Режим цепочки блоков шифрования. CBC работает только с кратными 16 байтам, поэтому вы также указываете способ дополнить ввод кратными 16 байтам.

Вот еще пример кода AES чтобы вы начали

person Zim-Zam O'Pootertoot    schedule 09.04.2013
comment
Так это тот же метод шифрования, что и RNCryptor? Потому что мне нужно будет расшифровать данные на iPad с помощью этой библиотеки. - person Johanneke; 10.04.2013
comment
Я изучил его и думаю, что смогу имитировать метод шифрования RNCryptor с помощью шифра, но мне нужен определенный формат для RNCryptor, чтобы расшифровать его на стороне клиента. Я начинаю думать, что мне может понадобиться прочитать данные в память и вывести зашифрованные данные в канальный поток вывода или что-то в этом роде... - person Johanneke; 10.04.2013
comment
Или, может быть, я должен просто использовать SSL, дох - person Johanneke; 10.04.2013
comment
В итоге я написал код для потокового шифрования на основе JNCryptor, поскольку SSL в конце концов не был решением. - person Johanneke; 16.04.2013