2016-10-09 3 views
-1

Ich möchte Dateien verschlüsseln und entschlüsseln. Während der Entschlüsselung möchte ich die ersten paar Bytes der Datei überspringen und nur den Rest entschlüsseln.Cipher Eingangsstrom überspringen

enthält hier drei Dateien

  1. input_file.txt - Eingabetextdatei für die Verschlüsselung
  2. output_file.txt - verschlüsselt input_file.txt Datei
  3. decrypted_file.txt - entschlüsselt output_file.txt Datei

Beispielcode:

import java.security.SecureRandom; 
import javax.crypto.Cipher; 
import javax.crypto.CipherInputStream; 
import javax.crypto.CipherOutputStream; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 

public class FileReadWrite { 

    public static byte[] getAESKey() { 
     SecureRandom secureRandom = new SecureRandom(); 
     byte[] bytes = new byte[32]; 
     secureRandom.nextBytes(bytes); 
     return bytes; 
    } 
/** 
* Method used to generate a random new iv 
* 
* @return Randomly generated iv 
*/ 
public static byte[] getAESIV() { 
    SecureRandom secureRandom = new SecureRandom(); 
    byte[] bytes = new byte[16]; 
    secureRandom.nextBytes(bytes); 
    return bytes; 
} 
public static void main(String[] args) throws Exception { 
    // TODO Auto-generated method stub 
    FileInputStream fin = new FileInputStream("/Users/emp/Research/Streams/input_file.txt"); 
    FileOutputStream fout = new FileOutputStream("/Users/emp/Research/Streams/output_file.txt"); 

    SecretKeySpec keySpec = null; 
    IvParameterSpec ivSpec = null; 
    Cipher ecipher = null; 
    Cipher dcipher = null; 
    byte[] keyBytes = getAESKey(); 
    byte[] ivBytes = getAESIV(); 
    // Creating keyspec and ivspec for generating cipher 
    keySpec = new SecretKeySpec(keyBytes,"AES"); 
    ivSpec = new IvParameterSpec(ivBytes); 
    try { 
     ecipher = Cipher.getInstance("AES/CTR/NoPadding"); 
     ecipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); 
    } catch (Exception e) { 
     System.out.println("Thus the exception occured during cipher generation is ::: "+e); 
    } 

    CipherOutputStream cout = new CipherOutputStream(fout, ecipher); 
    try { 
     int count = 0; 
     int BUFFER_SIZE = 1024; 
     byte[] bytearray = new byte[BUFFER_SIZE]; 
     while((count = fin.read(bytearray, 0, BUFFER_SIZE)) != -1) { 
      //fout.write(bytearray, 0, count); 
      cout.write(bytearray, 0, count); 
     } 
    } catch(Exception ex) { 
     System.out.println("Thus the exception occured is ::: "+ex); 
    } finally { 
     fin.close(); 
     fout.close(); 
     cout.close(); 
    } 

    fin = new FileInputStream("/Users/emp/Research/Streams/output_file.txt"); 
    fout = new FileOutputStream("/Users/emp/Research/Streams/decrypted_file.txt"); 

    try { 
     dcipher = Cipher.getInstance("AES/CTR/NoPadding"); 
     dcipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); 
    } catch (Exception e) { 
     System.out.println("Thus the exception occured during cipher generation is ::: "+e); 
    } 
    //fin.skip(1024); 
    CipherInputStream cin = new CipherInputStream(fin, dcipher); 
    try { 
     int count = 0; 
     int BUFFER_SIZE = 1024; 
     byte[] bytearray = new byte[BUFFER_SIZE]; 

     **//cin.read(bytearray, 0, 30);** 

     while((count = cin.read(bytearray, 0, BUFFER_SIZE)) != -1) { 
      //fout.write(bytearray, 0, count); 
      fout.write(bytearray, 0, count); 
     } 
    } catch(Exception ex) { 
     System.out.println("Thus the exception occured is ::: "+ex); 
    } finally { 
     fin.close(); 
     cin.close(); 
     fout.close(); 
    } 

    System.out.println("File read write completed successfully !!! "); 
} 
} 

Versuchte:

  1. Cipher Eingangsstrom überspringen - cin.skip(no_of_bytes) - das funktioniert nicht - diese entschlüsselt die gesamte Datei

  2. Datei-Eingabestream

    fin.skip(no_of_bytes); CipherInputStream cin = new 
    CipherInputStream(fin, cipher); 
    

    Dies gilt nicht überspringen entschlüssle die Datei. Die Ausgabedatei sieht wie verschlüsselt aus.

  3. Dummy lesen - Lesung und aus Chiffre Eingangsstrom ignorieren - das funktioniert

    //cin.read(bytearray, 0, 30); 
    

Bitte klären Sie mir folgendes:

  1. Welche skip und suchen Eingangsstrom intern tut?
  2. Warum funktioniert meine verschlüsselte Eingabe Stream-Suche nicht?
  3. Warum Cipher Input-Stream erfordert alle Bytes aus dem Stream (ich nehme an, so) für die Entschlüsselung gelesen werden? Wie funktioniert es?
+1

Ja, wenn Sie eine große Anzahl von Bytes in einer verschlüsselten Datei alles von der CipherInputStream auch entschlüsselt werden muss überspringen, wenn der CTR-Modus erlauben würde, das Überspringen (Begrenzung der Umsetzung). Siehe auch: http://stackoverflow.com/questions/23743842/random-access-inputstream-using-aes-ctr-mode-in-android – Robert

+0

So ist 'Dummy lesen' die einzige Lösung? – lsof

+0

Haben Sie die Antwort gelesen, die ich verlinkt habe? Es zeigt, wie man im CTR-Modus "überspringt". Es erfordert Dummy-Daten zu entschlüsseln, aber es ist nicht nötig, die verschlüsselte Datei zu lesen. – Robert

Antwort

0

Mit Bezug auf den Artikel, arbeitet

Random access InputStream using AES CTR mode in android

Nach der iv mit Offset-Wert Aktualisierung der Entschlüsselung in Ordnung. Hier

ist der aktualisierte Code

package Streams; 
import java.io.FileOutputStream; 
import java.io.FileInputStream; 
import java.math.BigInteger; 
import java.security.InvalidAlgorithmParameterException; 
import java.security.InvalidKeyException; 
import java.security.SecureRandom; 
import java.util.Arrays; 

import javax.crypto.Cipher; 
import javax.crypto.CipherInputStream; 
import javax.crypto.CipherOutputStream; 
import javax.crypto.ShortBufferException; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 

public class FileReadWrite { 
    private static final int AES_BLOCK_SIZE = 16; 

    public static final void jumpToOffset(final Cipher c, final SecretKeySpec aesKey, final IvParameterSpec iv, final long offset) { 
     if (!c.getAlgorithm().toUpperCase().startsWith("AES/CTR")) { 
      throw new IllegalArgumentException("Invalid algorithm, only AES/CTR mode supported"); 
     } 
     if (offset < 0) { 
      throw new IllegalArgumentException("Invalid offset"); 
     } 
     final int skip = (int) (offset % AES_BLOCK_SIZE); 
     final IvParameterSpec calculatedIVForOffset = calculateIVForOffset(iv, offset - skip); 
     try { 
      c.init(Cipher.ENCRYPT_MODE, aesKey, calculatedIVForOffset); 
      final byte[] skipBuffer = new byte[skip]; 
      c.update(skipBuffer, 0, skip, skipBuffer); 
      Arrays.fill(skipBuffer, (byte) 0); 
     } catch (ShortBufferException | InvalidKeyException | InvalidAlgorithmParameterException e) { 
      throw new IllegalStateException(e); 
     } 
    } 

    private static IvParameterSpec calculateIVForOffset(final IvParameterSpec iv, final long blockOffset) { 

     final BigInteger ivBI = new BigInteger(1, iv.getIV()); 
     final BigInteger ivForOffsetBI = ivBI.add(BigInteger.valueOf(blockOffset/AES_BLOCK_SIZE)); 
     final byte[] ivForOffsetBA = ivForOffsetBI.toByteArray(); 
     final IvParameterSpec ivForOffset; 
     if (ivForOffsetBA.length >= AES_BLOCK_SIZE) { 
      ivForOffset = new IvParameterSpec(ivForOffsetBA, ivForOffsetBA.length - AES_BLOCK_SIZE, AES_BLOCK_SIZE); 
     } else { 
      final byte[] ivForOffsetBASized = new byte[AES_BLOCK_SIZE]; 
      System.arraycopy(ivForOffsetBA, 0, ivForOffsetBASized, AES_BLOCK_SIZE - ivForOffsetBA.length, ivForOffsetBA.length); 
      ivForOffset = new IvParameterSpec(ivForOffsetBASized); 
     } 
     return ivForOffset; 
    } 

    public static byte[] getAESKey() { 
     SecureRandom secureRandom = new SecureRandom(); 
     byte[] bytes = new byte[32]; 
     secureRandom.nextBytes(bytes); 
     return bytes; 
    } 
    /** 
    * Method used to generate a random new iv 
    * 
    * @return Randomly generated iv 
    */ 
    public static byte[] getAESIV() { 
     SecureRandom secureRandom = new SecureRandom(); 
     byte[] bytes = new byte[16]; 
     secureRandom.nextBytes(bytes); 
     return bytes; 
    } 
    public static void main(String[] args) throws Exception { 
     // TODO Auto-generated method stub 
     FileInputStream fin = new FileInputStream("/Users/emp/Research/Streams/input_file.txt"); 
     FileOutputStream fout = new FileOutputStream("/Users/emp/Research/Streams/output_file.txt"); 

     SecretKeySpec keySpec = null; 
     IvParameterSpec ivSpec = null; 
     Cipher ecipher = null; 
     Cipher dcipher = null; 
     byte[] keyBytes = getAESKey(); 
     byte[] ivBytes = getAESIV(); 
     // Creating keyspec and ivspec for generating cipher 
     keySpec = new SecretKeySpec(keyBytes,"AES"); 
     ivSpec = new IvParameterSpec(ivBytes); 
     try { 
      ecipher = Cipher.getInstance("AES/CTR/NoPadding"); 
      ecipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); 
     } catch (Exception e) { 
      System.out.println("Thus the exception occured during cipher generation is ::: "+e); 
     } 

     CipherOutputStream cout = new CipherOutputStream(fout, ecipher); 
     try { 
      int count = 0; 
      int BUFFER_SIZE = 1024; 
      byte[] bytearray = new byte[BUFFER_SIZE]; 
      while((count = fin.read(bytearray, 0, BUFFER_SIZE)) != -1) { 
       //fout.write(bytearray, 0, count); 
       cout.write(bytearray, 0, count); 
      } 
     } catch(Exception ex) { 
      System.out.println("Thus the exception occured is ::: "+ex); 
     } finally { 
      fin.close(); 
      fout.close(); 
      cout.close(); 
     } 

     fin = new FileInputStream("/Users/emp/Research/Streams/output_file.txt"); 
     fout = new FileOutputStream("/Users/emp/Research/Streams/decrypted_file.txt"); 

     try { 
      dcipher = Cipher.getInstance("AES/CTR/NoPadding"); 
      dcipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); 
     } catch (Exception e) { 
      System.out.println("Thus the exception occured during cipher generation is ::: "+e); 
     } 

     fin.skip(1024); 
     jumpToOffset(dcipher, keySpec, ivSpec, 1024); 
     CipherInputStream cin = new CipherInputStream(fin, dcipher); 
     //cin.skip(1024); 
     try { 
      int count = 0; 
      int BUFFER_SIZE = 1024; 
      byte[] bytearray = new byte[BUFFER_SIZE]; 
      //cin.read(bytearray, 0, 30); 
      while((count = cin.read(bytearray, 0, BUFFER_SIZE)) != -1) { 
       //fout.write(bytearray, 0, count); 
       fout.write(bytearray, 0, count); 
      } 
     } catch(Exception ex) { 
      System.out.println("Thus the exception occured is ::: "+ex); 
     } finally { 
      fin.close(); 
      cin.close(); 
      fout.close(); 
     } 

     System.out.println("File read write completed successfully !!! "); 
    } 
} 
+0

Hallo allerseits, bisher hat die Frage nicht viele Informationen. Also, es wurde downvoted.Ich habe meine Frage mit genug Informationen bearbeitet und aktualisiert .. Aber immer noch ist der Downvote da und der stackoverflow-Account sagt: "Entschuldigung, dass wir keine Fragen von diesem Konto mehr annehmen", wenn ich versuche, eine neue Frage zu stellen - bitte helfen Sie mir Dies. – lsof