歲月如哥
          人生非夢
          posts - 50,comments - 144,trackbacks - 0
          大文件加密(實現在文件流中進行加密解密的方法)
          對一般小的文件可以使用這樣的加密解密方法(des):
          這里是把文件作為byte,全部緩存到內存中,如byte[] filebyte = getBytesFromFile(file_in);
          在內存中直接用加密類對其進行加密,如CryptoUtils.decrypt(filebyte, newkey);
          可是會產生一個問題,如果要加密的文件很大,比如要加密的文件 1G,而內存只有512M,這樣就會使byte很大,導致緩沖區溢出,現在尋求如果對大文件進行加密的方法。
                 
           /*
                   * 加密文件
                   * file1加密后產生file2密文
                   * 
          */


                  
          public static boolean enCryptoFile(String file1 ,String file2, String key)
                  
          {
                          
          //key轉為成為bytes
                          byte[] newkey = new byte[8];
                          newkey 
          = key.getBytes();
                          
          //輸入文件轉換成為bytes
                          File file_in = new File(file1);
                          
          byte[] filebyte = getBytesFromFile(file_in);
                          
          //定義輸出文件
                          File file_out = new File(file2);
                          FileOutputStream out 
          = null;
                          
          try {
                                  out 
          = new FileOutputStream(file_out);
                                  filebyte 
          = CryptoUtils.encrypt(filebyte, newkey);
                                  out.write(filebyte,
          0,filebyte.length);
                                  out.close();
                                  
          return true;
                          }
           catch (Exception e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                                  System.out.println(
          "File enCrypto Error!");
                          }

                          
          return false;
                  }

                  
                  
          /*
                   * 解密文件
                   * file1密文解密成file2明文
                   * key只能是8個byte
                   * 
          */


                  
          public static boolean deCryptoFile(String file1 ,String file2, String key)
                  
          {
                          
          //key轉為成為bytes
                          byte[] newkey = new byte[8];
                          newkey 
          = key.getBytes();
                          
          //輸入文件轉換成為bytes
                          File file_in = new File(file1);
                          
          byte[] filebyte = getBytesFromFile(file_in);
                          
          //定義輸出文件
                          File file_out = new File(file2);
                          FileOutputStream out 
          = null;
                          
          try {
                                  out 
          = new FileOutputStream(file_out);
                                  filebyte 
          = CryptoUtils.decrypt(filebyte, newkey);
                                  out.write(filebyte,
          0,filebyte.length);
                                  out.close();
                                  
          return true;
                          }
          catch(Exception e)
                          
          {
                                  e.printStackTrace();
                                  System.out.println(
          "File deCrypto Error!");
                                  
          return false;
                          }

                  }



          解決方法:
          經過研究發現1024個明文經過加密后變成1032個密文,
          這樣在進行流解密的時候,就需要讀1032個密文,解密成為1024個明文。
                 
           /*
                   * 加密文件
                   * file1加密后產生file2密文
                   * 
          */

                  
          public static boolean enoldCrByteFile(String file1 ,String file2, String key)
                  
          {
                          
          //key轉為成為bytes
                          byte[] newkey = new byte[8];
                          newkey 
          = key.getBytes();
                          
          try{
                          File file_in 
          = new File(file1);
                          File file_out 
          = new File(file2);
                          FileInputStream in 
          = new FileInputStream(file_in);
                          FileOutputStream out 
          =new FileOutputStream(file_out);
                          
          byte[] bytes = new byte[1024];
                          
          //String end = "<!~!>";
                          
          //System.out.print(end);
                          
          //byte [] bend = end.getBytes();
                          while((in.read(bytes))!=-1)
                          
          {
                                  
          byte[] bout = CryptoUtils.encrypt(bytes, newkey);
                                  System.out.println(bytes.length);
                                  System.out.println(bout.length);
                                  out.write(bout,
          0,1032);
                                  
          //out.write(bend,0,bend.length);
                          }

                          in.close();
                          out.close();
                          
          return true;
                          }
          catch(Exception e)
                          
          {
                                  e.printStackTrace();
                                  System.out.println(
          "File enCrypto Error!");
                                  
          return false;
                          }

                  }

                  

                  
          /*
                   * 解密文件
                   * file1密文解密成file2明文
                   * key只能是8個byte
                   * 
          */

                  
          public static boolean deoldCrByteFile(String file1 ,String file2, String key)
                  
          {
                          
          //key轉為成為bytes
                          byte[] newkey = new byte[8];
                          newkey 
          = key.getBytes();
                          
          try{
                          File file_in 
          = new File(file1);
                          File file_out 
          = new File(file2);
                          FileInputStream in 
          = new FileInputStream(file_in);
                          FileOutputStream out 
          =new FileOutputStream(file_out);
                          
          byte[] bytes = new byte[1032];
                          
          //String end = "<!~!>";
                          
          //System.out.print(end);
                          
          //byte [] bend = end.getBytes();
                          while((in.read(bytes))!=-1)
                          
          {
                                  
          byte[] bout = CryptoUtils.decrypt(bytes, newkey);
                                  out.write(bout,
          0,bout.length);
                                  
          //out.write(bend,0,bend.length);
                          }

                          in.close();
                          out.close();
                          
          return true;
                          }
          catch(Exception e)
                          
          {
                                  e.printStackTrace();
                                  System.out.println(
          "File deCrypto Error!");
                                  
          return false;
                          }

                  }



          重構成這樣,減少大對象創建。
          此方法是對文件流進行了byte切割,對流中的byte進行加密。加密后的byte保存到文件中。在解密的時候同樣進行分割文件byte流(這里的分割要與加密產生密文byte長度相同),這樣就可以實現占用內存少且快速高效的加密方法了。

           /*
                   * 加密文件
                   * file1加密后產生file2密文
                   * 
          */

                  
          public static boolean enCrByteFile(String file1 ,String file2, String key)
                  
          {        
                          Date date 
          = new Date(); //程序開始 時間
                          String dateStr1 = new Timestamp(date.getTime()).toString();
                          System.out.println(
          "加密開始time=" + dateStr1);

                          
          //key轉為成為bytes
                          byte[] newkey = new byte[8];
                          newkey 
          = key.getBytes();
                          
                  
          // 初始化一個用于des初始化的iv常量, 象形加密編碼的要求
                  IvParameterSpec iv = new IvParameterSpec(new byte[] 0x120x340x56,
                                  
          0x78, (byte0x90, (byte0xAB, (byte0xCD,
                                  (
          byte0xEF }
          );
                          
                  DESKeySpec dks 
          = null;
                          
          try {
                                  dks 
          = new DESKeySpec(newkey);
                          }
           catch (InvalidKeyException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }


                  SecretKeyFactory keyFactory 
          = null;
                          
          try {
                                  keyFactory 
          = SecretKeyFactory.getInstance(CIPHER_DES);
                          }
           catch (NoSuchAlgorithmException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }

                  SecretKey secureKey 
          = null;
                          
          try {
                                  secureKey 
          = keyFactory.generateSecret(dks);
                          }
           catch (InvalidKeySpecException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }


                  Cipher cipher 
          = null;
                          
          try {
                                  cipher 
          = Cipher.getInstance(CIPHER_DES_CBC);
                          }
           catch (NoSuchAlgorithmException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }
           catch (NoSuchPaddingException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }


                  
          try {
                                  cipher.init(Cipher.ENCRYPT_MODE, secureKey, iv);
                          }
           catch (InvalidKeyException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }
           catch (InvalidAlgorithmParameterException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }


                  
          //return cipher.doFinal(src);
                  

                          
          try{
                          File file_in 
          = new File(file1);
                          File file_out 
          = new File(file2);
                          FileInputStream in 
          = new FileInputStream(file_in);
                          FileOutputStream out 
          =new FileOutputStream(file_out);
                          
          byte[] bytes = new byte[1024];
                          
          //String end = "<!~!>";
                          
          //System.out.print(end);
                          
          //byte [] bend = end.getBytes();
                          while((in.read(bytes))!=-1)
                          
          {
                                  
          //byte[] bout = CryptoUtils.encrypt(bytes, newkey);
                                  byte[] bout = cipher.doFinal(bytes);//
                                  
          //System.out.println(bytes.length);
                                  
          //System.out.println(bout.length);
                                  out.write(bout,0,1032);
                                  
          //out.write(bend,0,bend.length);
                          }

                          in.close();
                          out.close();
                          
          return true;
                          }
          catch(Exception e)
                          
          {
                                  e.printStackTrace();
                                  System.out.println(
          "File enCrypto Error!");
                                  
          return false;
                          }

              }

                  

                  
          /*
                   * 解密文件
                   * file1密文解密成file2明文
                   * key只能是8個byte
                   * 
          */

                  
          public static boolean deCrByteFile(String file1 ,String file2, String key)
                  
          {
                          
          //key轉為成為bytes
                          byte[] newkey = new byte[8];
                          newkey 
          = key.getBytes();
                          
                          
                  
          // 初始化一個用于des初始化的iv常量, 象形加密編碼的要求
                  IvParameterSpec iv = new IvParameterSpec(new byte[] 0x120x340x56,
                                  
          0x78, (byte0x90, (byte0xAB, (byte0xCD,
                                  (
          byte0xEF }
          );
                          
                  DESKeySpec dks 
          = null;
                          
          try {
                                  dks 
          = new DESKeySpec(newkey);
                          }
           catch (InvalidKeyException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }


                  SecretKeyFactory keyFactory 
          = null;
                          
          try {
                                  keyFactory 
          = SecretKeyFactory.getInstance(CIPHER_DES);
                          }
           catch (NoSuchAlgorithmException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }

                  SecretKey secureKey 
          = null;
                          
          try {
                                  secureKey 
          = keyFactory.generateSecret(dks);
                          }
           catch (InvalidKeySpecException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }


                  Cipher cipher 
          = null;
                          
          try {
                                  cipher 
          = Cipher.getInstance(CIPHER_DES_CBC);
                          }
           catch (NoSuchAlgorithmException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }
           catch (NoSuchPaddingException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }

                  
          try {
                                  cipher.init(Cipher.ENCRYPT_MODE, secureKey, iv);
                          }
           catch (InvalidKeyException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }
           catch (InvalidAlgorithmParameterException e1) {
                                  
          // TODO Auto-generated catch block
                                  e1.printStackTrace();
                          }

                          
                          
          try{
                          File file_in 
          = new File(file1);
                          File file_out 
          = new File(file2);
                          FileInputStream in 
          = new FileInputStream(file_in);
                          FileOutputStream out 
          =new FileOutputStream(file_out);
                          
          byte[] bytes = new byte[1032];
                          
          //String end = "<!~!>";
                          
          //System.out.print(end);
                          
          //byte [] bend = end.getBytes();
                          while((in.read(bytes))!=-1)
                          
          {
                                  
          byte[] bout = CryptoUtils.decrypt(bytes, newkey);
                                  out.write(bout,
          0,bout.length);
                                  
          //out.write(bend,0,bend.length);
                          }

                          in.close();
                          out.close();
                          
          return true;
                          }
          catch(Exception e)
                          
          {
                                  e.printStackTrace();
                                  System.out.println(
          "File deCrypto Error!");
                                  
          return false;
                          }

                  }

                 
          環境pc、p3.0G、1G內存
          測試加密效率,對一個434M的文件進行加密,用時2分06秒,內存占用不超過20M(實際上就18M多一點),cpu占用率約為60%,感覺在加密過程中機器反應遲鈍。
          感覺這個效率還不錯,并沒有比全部緩存到內存中慢,但是占用內存卻很少。推薦以后使用此方法。

          加密開始time={SysUpTime = 141204 days 10:4:21} {Timestamp = Fri Aug 29 18:36:26 CST 2008}
          加密結束time={SysUpTime = 141204 days 10:25:28} {Timestamp = Fri Aug 29 18:38:32 CST 2008}

          這個效率還不錯,不過還有可以提高效率的地方,比如把1024換成des加密的使用的8位倍數的,減少一些最后補齊的加密;把des算法換成RC4等
          posted on 2008-08-30 15:22 歲月如歌 閱讀(10301) 評論(2)  編輯  收藏

          FeedBack:
          # re: 大文件加密(實現在文件流中進行加密解密的方法)zz
          2013-05-22 20:24 | twlkyao
          你好,CryptoUtils.decrypt(bytes, newkey);提示找不到是什么問題,這個是自己寫的嗎?  回復  更多評論
            
          # re: 大文件加密(實現在文件流中進行加密解密的方法)zz
          2013-05-26 19:06 | 天外來客歡迎您
          請問keyFactory = SecretKeyFactory.getInstance(CIPHER_DES);和cipher = Cipher.getInstance(CIPHER_DES_CBC);兩句中的算法分別是什么?謝謝。  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 合山市| 古丈县| 贺兰县| 保亭| 威海市| 垣曲县| 曲麻莱县| 玛沁县| 米脂县| 黑水县| 湖北省| 鄂托克旗| 舟山市| 尚义县| 江安县| 监利县| 长白| 汕尾市| 晋城| 淮滨县| 治多县| 濮阳市| 临沧市| 灵川县| 山东| 呼伦贝尔市| 桑日县| 交口县| 四平市| 郯城县| 黄山市| 宁安市| 谷城县| 鲁山县| 南平市| 平阳县| 准格尔旗| 固安县| 昆明市| 钟山县| 大连市|