2016-10-19 3 views
-2

저는 java의 로컬 저장소에서 인증서를 통해 파일의 암호를 해독합니다. 그러나 테이블을 포함하는 워드 프로세싱 파일의 경우 파일은 실제와 동일하게 유지되지 않습니다. 나는 정상적인 파일 입력/출력 스트림을 사용하고있다. 도움이되면 도움이 될 것입니다.테이블 및 구조체가 포함 된 텍스트 암호화

public int encryptFileWithpubkey(String filepath,PublicKey pubkey){ 
    int retval=0; 
    FileInputStream fis = null; 
    File file=null; 
    final String location = filepath; 
    PublicKey pubKey= pubkey; 
    try{ 
    try { 
     fis = AccessController.doPrivileged(
     new PrivilegedExceptionAction<FileInputStream>() { 
      public FileInputStream run() throws FileNotFoundException { 

       return new FileInputStream(location); 
      } 
     }); 
    } catch (PrivilegedActionException e) { 
     throw (FileNotFoundException) e.getException(); 
    } 
     InputStream is = fis; 
     //long length = file.length(); 

     byte[] bytes = new byte[fis.available()]; 
     int offset = 0; 
     int numRead = 0; 
     while (offset < bytes.length 
       && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { 
      offset += numRead; 
     } 
     is.close(); 
     file=null; 




      String encString="";   
      int iFixedLen=110; 
      if(bytes.length>=iFixedLen){ 

       int noOfBlocks=(int)Math.ceil((bytes.length/110.0)); 
      // System.out.println("Noof blocks :"+noOfBlocks); 
       for(int i=0;i<noOfBlocks;i++){ 
        byte[] tempStr=null; 
        if(i==noOfBlocks-1){ 
         //System.out.println("Last block"); 
         tempStr=new byte[(bytes.length-(i*iFixedLen))]; 
         System.arraycopy(bytes, (i*iFixedLen), tempStr, 0,(bytes.length-(i*iFixedLen))); 
        } 
        else 
        { 
         //System.out.println("i : "+i); 
         tempStr=new byte[iFixedLen]; 
         //tempStr=new byte[iFixedLen]; 
         System.arraycopy(bytes, (i*iFixedLen), tempStr, 0,iFixedLen); 
         //tempStr=plainText.substring(0,110) ; 
         //plainText=plainText.substring(110); 
        } 
        encString+= encryptBytes(tempStr,pubKey)+" "; 
       } 
       encString=encString.substring(0,encString.length()-1); 
       retval=noOfBlocks; 
      }else{ 
       encString=encryptBytes(bytes,pubKey); 
       retval=1; 

      } 

     FileOutputStream fos = null; 
    try { 
     fos = AccessController.doPrivileged(
     new PrivilegedExceptionAction<FileOutputStream>() { 
      public FileOutputStream run() throws FileNotFoundException { 

       return new FileOutputStream(location); 
      } 
     }); 
    } catch (PrivilegedActionException e) { 
     throw (FileNotFoundException) e.getException(); 
    } 
    fos.write(encString.getBytes()); 
    fos.close(); 
    }catch(Exception e){ 
     e.printStackTrace(); 
     return 0; 
    } 
return retval; 
} 

encryptBytes 기능 followes : 당신은 여기 책에 거의 모든 실수를 한

public String encryptBytes(byte[] rawData,PublicKey pubkey){ 
     String retval=null; 

     try{ 

     byte[] rawByteData=rawData; 
     Cipher cp=Cipher.getInstance("RSA/ECB/PKCS1PADDING"); 
     cp.init(Cipher.ENCRYPT_MODE,pubkey); 
     byte[] getDat=cp.doFinal(rawByteData); 

     retval=java.util.Base64.getEncoder().encodeToString(getDat); 

     }catch(Exception e) 
     { 
     e.printStackTrace(); 
     } 
     return retval; 
    } 
+0

코드 어딘가에 버그가 있습니다. 이것은 그것을 보지 않고도 말할 수 있습니다. – Henry

+0

@Henry 간단한 텍스트 내용에는 문제가 없지만 다이어그램과 테이블의 경우 제대로 작동하지 않습니다. –

+0

다이어그램과 테이블을 암호화 할 때 코드에 버그가 있습니다. 어떤 다른 종류의 대답이 예상 될 수 있습니까? – EJP

답변

0

.

 InputStream is = fis; 
     //long length = file.length(); 

     byte[] bytes = new byte[fis.available()]; 

InputStream.available()은 입력 스트림의 길이를 나타내는 지표가 아닙니다. Javadoc을 참조하십시오. 여기서 Javadoc은 여러분이 여기서하는 일에 대해 특별한 경고를합니다. I/O를 수행 할 때 실제로 고정 된 크기의 버퍼를 사용할 수 있으며 전체 파일을 메모리로 읽을 필요가 거의 없습니다. 컴파일러는 그것을하지 않습니다 : 왜 그래야합니까?

 int offset = 0; 
     int numRead = 0; 
     while (offset < bytes.length 
       && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) { 
      offset += numRead; 
     } 
     is.close(); 
     file=null; 

file = null; 문은 여기 무의미, 나는 아래에 표시됩니다으로 전체 루프는 생략 할 수있다.

  String encString=""; 

String은 바이너리 데이터 용 컨테이너가 아닙니다.

  int iFixedLen=110; 

어디에서 마법 번호 110이 나왔습니까?

  if(bytes.length>=iFixedLen){ 

       int noOfBlocks=(int)Math.ceil((bytes.length/110.0)); 
      // System.out.println("Noof blocks :"+noOfBlocks); 
       for(int i=0;i<noOfBlocks;i++){ 
        byte[] tempStr=null; 
        if(i==noOfBlocks-1){ 
         //System.out.println("Last block"); 
         tempStr=new byte[(bytes.length-(i*iFixedLen))]; 
         System.arraycopy(bytes, (i*iFixedLen), tempStr, 0,(bytes.length-(i*iFixedLen))); 
        } 
        else 
        { 
         //System.out.println("i : "+i); 
         tempStr=new byte[iFixedLen]; 
         //tempStr=new byte[iFixedLen]; 
         System.arraycopy(bytes, (i*iFixedLen), tempStr, 0,iFixedLen); 
         //tempStr=plainText.substring(0,110) ; 
         //plainText=plainText.substring(110); 
        } 
        encString+= encryptBytes(tempStr,pubKey)+" "; 
       } 
       encString=encString.substring(0,encString.length()-1); 
       retval=noOfBlocks; 
      }else{ 
       encString=encryptBytes(bytes,pubKey); 
       retval=1; 

      } 

나는이 모든이해야 할 내용을 아무 생각이 없다, 그러나 당신은 110 바이트 또는 문자의 블록을 사용해서는 안 또는 그들이, 또는 바이트 배열의 형태로 암호화 된 데이터를 변환 어떤 문자열에 4 개의 공백을 추가해서는 안됩니다.

여기서 실제 암호화로 인해 원래 바이트 배열을 작성하고 전체적인 문제를 피할 수 있습니다.

encryptBytes() 메서드를 게시하지 않았으므로 추가로 주석을 달 수 없습니다. 그것은 이미 "문서"에서 연재되는 바이너리 데이터에 작동하기 때문에 파일이 테이블 또는 다른 구조가 포함되어 있는지 여부를

fos.close(); 
    }catch(Exception e){ 
     e.printStackTrace(); 
     return 0; 
    } 
return retval; 
} 
+0

함수 encryptBytes()는 암호화 된 데이터의 문자열 값을 반환합니다. –

+0

"마법 번호"110은 모든 RSA 청크가 동일한 길이가 아니라는 사실을 해결하기 위해 노력하는 잘못된 방법에서 왔습니다. –

0

는 현대 암호화 완전히 무관하다.

원본 파일의 일부 청크에 RSA를 적용하려고합니다. 입력이 패딩을 고려한 RSA 모듈러스보다 작은 지 확인해야하기 때문에 이것은 매우 까다로운 일입니다. 그런 다음 각 암호문 청크의 길이가 정확히 같아야 암호 해독 중에 어느 바이트가 어떤 청크에 속하는지 알 수 있습니다. RSA에서는 출력에 항상 같은 바이트 수를 보장하지 않습니다. 패딩 된 입력에 비해 작을 수 있습니다. 따라서 암호문 청크를 일관되게 채울 필요가 있습니다.

더 좋은 아이디어는 hybrid encryption을 사용하는 것입니다. AES를 사용하여 실제 데이터를 암호화하고 RSA를 사용하여 임의로 생성 된 AES 키를 암호화 할 수 있습니다.당신은 AES 암호화를 수행하는 경우

물론
4 bytes - Length of the RSA-encrypted AES key (= x) 
x bytes - RSA-encrypted AES key 
remaining bytes - AES-encrypted file 

는 어떻게 초기화 벡터를 처리하는 방법 및 여부를 작동 모드, 패딩 모드에 대해 생각해야 할 것입니다 : 간단한 형식은 쉽게 할 수 있어야 인증 된 암호화를 추가하려고합니다.

+0

은 110 분할을위한 패딩 공간이 될 수 있습니다. 아나모픽을 수행하고 있습니다. 감사합니다. Artjom은 하이브리드 암호화를 살펴볼 것입니다. –

+0

하지만 대칭 키는 모든 경우에 키를 공유하는 데 방해가되지만 내 경우에는 충분하지 않습니다. 더 효율적으로 패딩을 도와 주실 수 있습니까? (이 경우) –

+0

아니요, 오해하셨습니다. AES 키는 개인 RSA 키를 가지고있는 사람 만 복구 할 수 있습니다. –

관련 문제