大文件加密(实现在文件流中进行加密解密的方法)
对一般小的文件可以使用这样的加密解密方法(des):
这里是把文件作为byte,全部缓存到
内存中,如byte[] filebyte = getBytesFromFile(file_in);
在内存中直接用加密类对其进行加密,如CryptoUtils.decrypt(filebyte, newkey);
可是会产生一个
问题,如果要加密的文件很大,比如要加密的文件 1G,而内存只有512M,这样就会使byte很大,导致缓冲区溢出,现在寻求如果对大文件进行加密的方法。
       

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

 public static boolean enCryptoFile(String file1 ,String file2, String key)
        public static boolean enCryptoFile(String file1 ,String file2, String key)

 
         {
{
 //key转为成为bytes
                //key转为成为bytes
 byte[] newkey = new byte[8];
                byte[] newkey = new byte[8];
 newkey = key.getBytes();
                newkey = key.getBytes();
 //输入文件转换成为bytes
                //输入文件转换成为bytes
 File file_in = new File(file1);
                File file_in = new File(file1);
 byte[] filebyte = getBytesFromFile(file_in);
                byte[] filebyte = getBytesFromFile(file_in);
 //定义输出文件
                //定义输出文件
 File file_out = new File(file2);
                File file_out = new File(file2);
 FileOutputStream out = null;
                FileOutputStream out = null;

 try
                try  {
{
 out = new FileOutputStream(file_out);
                        out = new FileOutputStream(file_out);
 filebyte = CryptoUtils.encrypt(filebyte, newkey);
                        filebyte = CryptoUtils.encrypt(filebyte, newkey);
 out.write(filebyte,0,filebyte.length);
                        out.write(filebyte,0,filebyte.length);
 out.close();
                        out.close();
 return true;
                        return true;

 } catch (Exception e1)
                } catch (Exception e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();
 System.out.println("File enCrypto Error!");
                        System.out.println("File enCrypto Error!");
 }
                }
 return false;
                return false;
 }
        }
 
        

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

 public static boolean deCryptoFile(String file1 ,String file2, String key)
        public static boolean deCryptoFile(String file1 ,String file2, String key)

 
         {
{
 //key转为成为bytes
                //key转为成为bytes
 byte[] newkey = new byte[8];
                byte[] newkey = new byte[8];
 newkey = key.getBytes();
                newkey = key.getBytes();
 //输入文件转换成为bytes
                //输入文件转换成为bytes
 File file_in = new File(file1);
                File file_in = new File(file1);
 byte[] filebyte = getBytesFromFile(file_in);
                byte[] filebyte = getBytesFromFile(file_in);
 //定义输出文件
                //定义输出文件
 File file_out = new File(file2);
                File file_out = new File(file2);
 FileOutputStream out = null;
                FileOutputStream out = null;

 try
                try  {
{
 out = new FileOutputStream(file_out);
                        out = new FileOutputStream(file_out);
 filebyte = CryptoUtils.decrypt(filebyte, newkey);
                        filebyte = CryptoUtils.decrypt(filebyte, newkey);
 out.write(filebyte,0,filebyte.length);
                        out.write(filebyte,0,filebyte.length);
 out.close();
                        out.close();
 return true;
                        return true;
 }catch(Exception e)
                }catch(Exception e)

 
                 {
{
 e.printStackTrace();
                        e.printStackTrace();
 System.out.println("File deCrypto Error!");
                        System.out.println("File deCrypto Error!");
 return false;
                        return false;
 }
                }
 }
        }

解决方法:
经过研究发现1024个明文经过加密后变成1032个密文,
这样在进行流解密的时候,就需要读1032个密文,解密成为1024个明文。
       

 /**//*
 /**//*
 * 加密文件
         * 加密文件
 * file1加密后产生file2密文
         * file1加密后产生file2密文
 * */
         * */
 public static boolean enoldCrByteFile(String file1 ,String file2, String key)
        public static boolean enoldCrByteFile(String file1 ,String file2, String key)

 
         {
{
 //key转为成为bytes
                //key转为成为bytes
 byte[] newkey = new byte[8];
                byte[] newkey = new byte[8];
 newkey = key.getBytes();
                newkey = key.getBytes();

 try
                try {
{
 File file_in = new File(file1);
                File file_in = new File(file1);
 File file_out = new File(file2);
                File file_out = new File(file2);
 FileInputStream in = new FileInputStream(file_in);
                FileInputStream in = new FileInputStream(file_in);
 FileOutputStream out =new FileOutputStream(file_out);
                FileOutputStream out =new FileOutputStream(file_out);
 byte[] bytes = new byte[1024];
                byte[] bytes = new byte[1024];
 //String end = "<!~!>";
                //String end = "<!~!>";
 //System.out.print(end);
                //System.out.print(end);
 //byte [] bend = end.getBytes();
                //byte [] bend = end.getBytes();
 while((in.read(bytes))!=-1)
                while((in.read(bytes))!=-1)

 
                 {
{
 byte[] bout = CryptoUtils.encrypt(bytes, newkey);
                        byte[] bout = CryptoUtils.encrypt(bytes, newkey);
 System.out.println(bytes.length);
                        System.out.println(bytes.length);
 System.out.println(bout.length);
                        System.out.println(bout.length);
 out.write(bout,0,1032);
                        out.write(bout,0,1032);
 //out.write(bend,0,bend.length);
                        //out.write(bend,0,bend.length);
 }
                }
 in.close();
                in.close();
 out.close();
                out.close();
 return true;
                return true;
 }catch(Exception e)
                }catch(Exception e)

 
                 {
{
 e.printStackTrace();
                        e.printStackTrace();
 System.out.println("File enCrypto Error!");
                        System.out.println("File enCrypto Error!");
 return false;
                        return false;
 }
                }
 }
        }
 
        


 /**//*
        /**//*
 * 解密文件
         * 解密文件
 * file1密文解密成file2明文
         * file1密文解密成file2明文
 * key只能是8个byte
         * key只能是8个byte
 * */
         * */
 public static boolean deoldCrByteFile(String file1 ,String file2, String key)
        public static boolean deoldCrByteFile(String file1 ,String file2, String key)

 
         {
{
 //key转为成为bytes
                //key转为成为bytes
 byte[] newkey = new byte[8];
                byte[] newkey = new byte[8];
 newkey = key.getBytes();
                newkey = key.getBytes();

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

 
                 {
{
 byte[] bout = CryptoUtils.decrypt(bytes, newkey);
                        byte[] bout = CryptoUtils.decrypt(bytes, newkey);
 out.write(bout,0,bout.length);
                        out.write(bout,0,bout.length);
 //out.write(bend,0,bend.length);
                        //out.write(bend,0,bend.length);
 }
                }
 in.close();
                in.close();
 out.close();
                out.close();
 return true;
                return true;
 }catch(Exception e)
                }catch(Exception e)

 
                 {
{
 e.printStackTrace();
                        e.printStackTrace();
 System.out.println("File deCrypto Error!");
                        System.out.println("File deCrypto Error!");
 return false;
                        return false;
 }
                }
 }
        }

重构成这样,减少大对象创建。
此方法是对文件流进行了byte切割,对流中的byte进行加密。加密后的byte保存到文件中。在解密的时候同样进行分割文件byte流(这里的分割要与加密产生密文byte长度相同),这样就可以实现占用内存少且快速高效的加密方法了。

 /**//*
 /**//*
 * 加密文件
         * 加密文件
 * file1加密后产生file2密文
         * file1加密后产生file2密文
 * */
         * */
 public static boolean enCrByteFile(String file1 ,String file2, String key)
        public static boolean enCrByteFile(String file1 ,String file2, String key)

 
         {
{        
 Date date = new Date(); //程序开始 时间
                Date date = new Date(); //程序开始 时间
 String dateStr1 = new Timestamp(date.getTime()).toString();
                String dateStr1 = new Timestamp(date.getTime()).toString();
 System.out.println("加密开始time=" + dateStr1);
                System.out.println("加密开始time=" + dateStr1);

 //key转为成为bytes
                //key转为成为bytes
 byte[] newkey = new byte[8];
                byte[] newkey = new byte[8];
 newkey = key.getBytes();
                newkey = key.getBytes();
 
                
 // 初始化一个用于des初始化的iv常量, 象形加密编码的要求
        // 初始化一个用于des初始化的iv常量, 象形加密编码的要求

 IvParameterSpec iv = new IvParameterSpec(new byte[]
        IvParameterSpec iv = new IvParameterSpec(new byte[]  { 0x12, 0x34, 0x56,
{ 0x12, 0x34, 0x56,
 0x78, (byte) 0x90, (byte) 0xAB, (byte) 0xCD,
                        0x78, (byte) 0x90, (byte) 0xAB, (byte) 0xCD,
 (byte) 0xEF });
                        (byte) 0xEF });
 
                
 DESKeySpec dks = null;
        DESKeySpec dks = null;

 try
                try  {
{
 dks = new DESKeySpec(newkey);
                        dks = new DESKeySpec(newkey);

 } catch (InvalidKeyException e1)
                } catch (InvalidKeyException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();
 }
                }

 SecretKeyFactory keyFactory = null;
        SecretKeyFactory keyFactory = null;

 try
                try  {
{
 keyFactory = SecretKeyFactory.getInstance(CIPHER_DES);
                        keyFactory = SecretKeyFactory.getInstance(CIPHER_DES);

 } catch (NoSuchAlgorithmException e1)
                } catch (NoSuchAlgorithmException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();
 }
                }
 SecretKey secureKey = null;
        SecretKey secureKey = null;

 try
                try  {
{
 secureKey = keyFactory.generateSecret(dks);
                        secureKey = keyFactory.generateSecret(dks);

 } catch (InvalidKeySpecException e1)
                } catch (InvalidKeySpecException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();
 }
                }

 Cipher cipher = null;
        Cipher cipher = null;

 try
                try  {
{
 cipher = Cipher.getInstance(CIPHER_DES_CBC);
                        cipher = Cipher.getInstance(CIPHER_DES_CBC);

 } catch (NoSuchAlgorithmException e1)
                } catch (NoSuchAlgorithmException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();

 } catch (NoSuchPaddingException e1)
                } catch (NoSuchPaddingException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();
 }
                }


 try
        try  {
{
 cipher.init(Cipher.ENCRYPT_MODE, secureKey, iv);
                        cipher.init(Cipher.ENCRYPT_MODE, secureKey, iv);

 } catch (InvalidKeyException e1)
                } catch (InvalidKeyException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();

 } catch (InvalidAlgorithmParameterException e1)
                } catch (InvalidAlgorithmParameterException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();
 }
                }

 //return cipher.doFinal(src);
        //return cipher.doFinal(src);
 
        


 try
                try {
{
 File file_in = new File(file1);
                File file_in = new File(file1);
 File file_out = new File(file2);
                File file_out = new File(file2);
 FileInputStream in = new FileInputStream(file_in);
                FileInputStream in = new FileInputStream(file_in);
 FileOutputStream out =new FileOutputStream(file_out);
                FileOutputStream out =new FileOutputStream(file_out);
 byte[] bytes = new byte[1024];
                byte[] bytes = new byte[1024];
 //String end = "<!~!>";
                //String end = "<!~!>";
 //System.out.print(end);
                //System.out.print(end);
 //byte [] bend = end.getBytes();
                //byte [] bend = end.getBytes();
 while((in.read(bytes))!=-1)
                while((in.read(bytes))!=-1)

 
                 {
{
 //byte[] bout = CryptoUtils.encrypt(bytes, newkey);
                        //byte[] bout = CryptoUtils.encrypt(bytes, newkey);
 byte[] bout = cipher.doFinal(bytes);//
                        byte[] bout = cipher.doFinal(bytes);//
 //System.out.println(bytes.length);
                        //System.out.println(bytes.length);
 //System.out.println(bout.length);
                        //System.out.println(bout.length);
 out.write(bout,0,1032);
                        out.write(bout,0,1032);
 //out.write(bend,0,bend.length);
                        //out.write(bend,0,bend.length);
 }
                }
 in.close();
                in.close();
 out.close();
                out.close();
 return true;
                return true;
 }catch(Exception e)
                }catch(Exception e)

 
                 {
{
 e.printStackTrace();
                        e.printStackTrace();
 System.out.println("File enCrypto Error!");
                        System.out.println("File enCrypto Error!");
 return false;
                        return false;
 }
                }
 }
    }
 
        


 /**//*
        /**//*
 * 解密文件
         * 解密文件
 * file1密文解密成file2明文
         * file1密文解密成file2明文
 * key只能是8个byte
         * key只能是8个byte
 * */
         * */
 public static boolean deCrByteFile(String file1 ,String file2, String key)
        public static boolean deCrByteFile(String file1 ,String file2, String key)

 
         {
{
 //key转为成为bytes
                //key转为成为bytes
 byte[] newkey = new byte[8];
                byte[] newkey = new byte[8];
 newkey = key.getBytes();
                newkey = key.getBytes();
 
                
 
                
 // 初始化一个用于des初始化的iv常量, 象形加密编码的要求
        // 初始化一个用于des初始化的iv常量, 象形加密编码的要求

 IvParameterSpec iv = new IvParameterSpec(new byte[]
        IvParameterSpec iv = new IvParameterSpec(new byte[]  { 0x12, 0x34, 0x56,
{ 0x12, 0x34, 0x56,
 0x78, (byte) 0x90, (byte) 0xAB, (byte) 0xCD,
                        0x78, (byte) 0x90, (byte) 0xAB, (byte) 0xCD,
 (byte) 0xEF });
                        (byte) 0xEF });
 
                
 DESKeySpec dks = null;
        DESKeySpec dks = null;

 try
                try  {
{
 dks = new DESKeySpec(newkey);
                        dks = new DESKeySpec(newkey);

 } catch (InvalidKeyException e1)
                } catch (InvalidKeyException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();
 }
                }

 SecretKeyFactory keyFactory = null;
        SecretKeyFactory keyFactory = null;

 try
                try  {
{
 keyFactory = SecretKeyFactory.getInstance(CIPHER_DES);
                        keyFactory = SecretKeyFactory.getInstance(CIPHER_DES);

 } catch (NoSuchAlgorithmException e1)
                } catch (NoSuchAlgorithmException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();
 }
                }
 SecretKey secureKey = null;
        SecretKey secureKey = null;

 try
                try  {
{
 secureKey = keyFactory.generateSecret(dks);
                        secureKey = keyFactory.generateSecret(dks);

 } catch (InvalidKeySpecException e1)
                } catch (InvalidKeySpecException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();
 }
                }

 Cipher cipher = null;
        Cipher cipher = null;

 try
                try  {
{
 cipher = Cipher.getInstance(CIPHER_DES_CBC);
                        cipher = Cipher.getInstance(CIPHER_DES_CBC);

 } catch (NoSuchAlgorithmException e1)
                } catch (NoSuchAlgorithmException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();

 } catch (NoSuchPaddingException e1)
                } catch (NoSuchPaddingException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();
 }
                }

 try
        try  {
{
 cipher.init(Cipher.ENCRYPT_MODE, secureKey, iv);
                        cipher.init(Cipher.ENCRYPT_MODE, secureKey, iv);

 } catch (InvalidKeyException e1)
                } catch (InvalidKeyException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();

 } catch (InvalidAlgorithmParameterException e1)
                } catch (InvalidAlgorithmParameterException e1)  {
{
 // TODO Auto-generated catch block
                        // TODO Auto-generated catch block
 e1.printStackTrace();
                        e1.printStackTrace();
 }
                }
 
                

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

 
                 {
{
 byte[] bout = CryptoUtils.decrypt(bytes, newkey);
                        byte[] bout = CryptoUtils.decrypt(bytes, newkey);
 out.write(bout,0,bout.length);
                        out.write(bout,0,bout.length);
 //out.write(bend,0,bend.length);
                        //out.write(bend,0,bend.length);
 }
                }
 in.close();
                in.close();
 out.close();
                out.close();
 return true;
                return true;
 }catch(Exception e)
                }catch(Exception e)

 
                 {
{
 e.printStackTrace();
                        e.printStackTrace();
 System.out.println("File deCrypto Error!");
                        System.out.println("File deCrypto Error!");
 return false;
                        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 
岁月如歌 阅读(10328) 
评论(2)  编辑  收藏