Зашифровать файл, добавив упакованный ключ в уникальный файл

1

Я пытаюсь зашифровать файл, используя ключ AES. Завернутый в пару ключей RSA.

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

Проблема в том, что я шифрую файл в блоках 1024 байта. Итак, для дешифрования мне нужно взять последние байты файла (не первые 256, потому что они являются ключом)

Итак, на этом изображении вы можете увидеть процессы

<a href='http://postimg.org/image/htmelww63/' target='_blank'><img src='http://s1.postimg.org/htmelww63/Blank_Flowchart_New_Page.jpg' border='0' alt="Blank Flowchart New Page" /></a>

Поэтому проблема заключается в том, что мне нужно расшифровать файл, кроме первых 256 байтов. Я не могу найти рабочий алгоритм...

Здесь код для шифрования:

public static void fileEncripWrapped(File in, File out, PublicKey pub, byte [] key) {  

    try {
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");

        //Encrypting wrapped key      
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.WRAP_MODE, pub);
        byte[] encKey = cipher.wrap(keySpec);

        FileOutputStream osAppend  = new FileOutputStream(out);

        osAppend.write(encKey);
        osAppend.close();


        // Crypting the file 
         cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);

        FileInputStream is = new FileInputStream(in);
        CipherOutputStream os = new CipherOutputStream(new FileOutputStream(out, true), cipher);

        copy(is, os);

        is.close();
        os.close();

    } catch (Exception ex) {
        System.err.println("Ha succeït un error xifrant: " + ex);
    }
}

Это код, который я использую для копирования inputStream в outputStream в блоках 1024 байта.

private static void copy(InputStream is, OutputStream os) throws IOException {
    int i;
    byte[] b = new byte[1024];
    while((i=is.read(b))!=-1) {
       os.write(b, 0, i);
    }
}

Теперь проблема заключается в том, чтобы раскрыть:

public static void fileUncryptWrapped(File in, File out, PrivateKey priv) { 

   try {

       Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
       cipher.init(Cipher.UNWRAP_MODE, priv);

       //First we must to take the wrapped key in the first 256 bytes of the file: 
       byte[] bufferKey = new byte[256];
       InputStream is = new FileInputStream(in);
       if (is.read(bufferKey) != bufferKey.length) { 

       }
       is.close();

       Key ky = cipher.unwrap(bufferKey, "AES", Cipher.SECRET_KEY);¡

       // Now we must to uncrypt the rest of the file
       cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
       cipher.init(Cipher.DECRYPT_MODE, ky);

       CipherInputStream ix = new CipherInputStream(new FileInputStream(in), cipher);
       FileOutputStream os = new FileOutputStream(out);

       copy(ix, os);

       ix.close();
       os.close();

   } catch (Exception ex) {
       System.err.println("Ha succeït un error xifrant: " + ex);
   }
}

Какие изменения мне нужно сделать в функции копирования для приема байтов после первых 256? Я пробовал что-то подобное, но это не работает...

// Get the size of the file
long streamLength = inputStream.available();

if (streamLength > Integer.MAX_VALUE) {
    // File is too large
}

// Create the byte array to hold the data
byte[] bytes = new byte[1024];

// Read in the bytes
int block_size = 1024;
int offset = 256;
int numRead = 0;
while (offset < (int) streamLength && (numRead = inputStream.read(bytes, offset,  block_size)) >= 0) {
    offset += numRead;
    outputStream.write(bytes, 0 , block_size );
 }
Теги:
encryption
aes
rsa

1 ответ

1
Лучший ответ

Код расшифровки должен выглядеть примерно так:

public static void fileDecryptWrapped(File in, File out, PrivateKey priv)
        throws GeneralSecurityException, IOException {

    Signature signature = Signature.getInstance("SHA1WITHRSA");
    signature.initSign(priv);
    signature.update("test".getBytes());
    byte[] bufferKey = signature.sign();

    // First we must to take the wrapped key in the first bufferKey.length bytes of the file
    InputStream is = new FileInputStream(in);
    if (is.read(bufferKey) != bufferKey.length) { 
        is.close();
        throw new IllegalStateException("Too short file");
    }

    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.UNWRAP_MODE, priv);
    Key aesKey = cipher.unwrap(bufferKey, "AES", Cipher.SECRET_KEY);

    // Now we must to decrypt the rest of the file
    cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
    cipher.init(Cipher.DECRYPT_MODE, aesKey);

    CipherInputStream ix = new CipherInputStream(is, cipher);
    FileOutputStream os = new FileOutputStream(out);

    copy(ix, os);

    ix.close();
    os.close();
}

Обратите внимание, что тот же FileInputStream после прочтения ключа передается CipherInputStream без изменений.

Проблема, которую я вижу с вашим подходом, в зашифрованном файле отсутствует структура. Например, использование ключа без 2K RSA будет сильно терпеть неудачу, поскольку алгоритм дешифрования всегда ожидает 256 байтов завернутого ключа.

  • 0
    Хорошо, но я могу вернуть свой завернутый ключ. Таким образом, проблема в основном заключается в том, как прочитать остальную часть файла в блоках по 1024. Как вы думаете, я должен сделать подход?
  • 0
    CipherInputStream делает это для вас.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню