2016-10-19 4 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キーを暗号化することができます。シンプルなフォーマットを行うのは簡単なはず:

もちろん
4 bytes - Length of the RSA-encrypted AES key (= x) 
x bytes - RSA-encrypted AES key 
remaining bytes - AES-encrypted file 

、あなたはAES暗号化をやっている場合、あなたは動作モードについて考えなければならないだろう、初期化ベクトルとするかどうかを処理するために、どのようにパディングモード、認証された暗号化を追加する必要があります。

+0

は、110分割のためにパディングスペースを追加することができます。これはアナモリを実行しています。ありがとう。Artjomはハイブリッド暗号化を検討します。 –

+0

しかし、対称鍵は私の場合はすべてに鍵を共有するのに支障がありますが、それは十分ではありません。あなたはより効率的にパディングを手伝ってくれますか?(この場合) –

+0

いいえ、あなたは間違っています。 AESキーは、秘密のRSAキーを保持している人だけが回復可能です。 –

関連する問題