ice world

          There is nothing too difficult if you put your heart into it.
          posts - 104, comments - 103, trackbacks - 0, articles - 0
          本工具類(lèi)經(jīng)過(guò)測(cè)試可用,之前寫(xiě)的沒(méi)有使用CipherInputStream和CipherOutputStream,生成的加密文件與源文件大小不一致,加密時(shí)沒(méi)有問(wèn)題,解密時(shí)總是拋出如下異常:
          Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
              at com
          .sun.crypto.provider.SunJCE_f.b(DashoA13*..)
              at com
          .sun.crypto.provider.SunJCE_f.b(DashoA13*..)
              at com
          .sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..)
              at javax
          .crypto.Cipher.doFinal(DashoA13*..)


          其中BASE64底層依賴(lài)庫(kù)沒(méi)有使用SUN的,而是下載的“javabase64-1.3.1.jar”

          DESUtils.java
          package demo.security;

          import java.io.File;
          import java.io.FileInputStream;
          import java.io.FileOutputStream;
          import java.io.InputStream;
          import java.io.OutputStream;
          import java.security.Key;
          import java.security.SecureRandom;

          import javax.crypto.Cipher;
          import javax.crypto.CipherInputStream;
          import javax.crypto.CipherOutputStream;
          import javax.crypto.KeyGenerator;
          import javax.crypto.SecretKey;
          import javax.crypto.SecretKeyFactory;
          import javax.crypto.spec.DESKeySpec;

          /**
           * <p>
           * DES加密解密工具包
           * </p>
           * 
           * 
          @author IceWee
           * @date 2012-5-19
           * 
          @version 1.0
           
          */

          public class DESUtils {
              
              
          private static final String ALGORITHM = "DES";
              
          private static final int CACHE_SIZE = 1024;

              
          /**
               * <p>
               * 生成隨機(jī)密鑰
               * </p>
               * 
               * 
          @return
               * 
          @throws Exception
               
          */

              
          public static String getSecretKey() throws Exception {
                  
          return getSecretKey(null);
              }

              
              
          /**
               * <p>
               * 生成密鑰
               * </p>
               * 
               * 
          @param seed 密鑰種子
               * 
          @return
               * 
          @throws Exception
               
          */

              
          public static String getSecretKey(String seed) throws Exception {
                  SecureRandom secureRandom;
                  
          if (seed != null && !"".equals(seed))
                      secureRandom 
          = new SecureRandom(seed.getBytes());
                  
          else
                      secureRandom 
          = new SecureRandom();
                  KeyGenerator keyGenerator 
          = KeyGenerator.getInstance(ALGORITHM);
                  keyGenerator.init(secureRandom);
                  SecretKey secretKey 
          = keyGenerator.generateKey();
                  
          return Base64Utils.encode(secretKey.getEncoded());
              }

              
              
          /**
               * <p>
               * 加密
               * </p>
               * 
               * 
          @param data
               * 
          @param key
               * 
          @return
               * 
          @throws Exception
               
          */

              
          public static byte[] encrypt(byte[] data, String key) throws Exception {
                  Key k 
          = toKey(Base64Utils.decode(key));
                  Cipher cipher 
          = Cipher.getInstance(ALGORITHM);
                  cipher.init(Cipher.ENCRYPT_MODE, k);
                  
          return cipher.doFinal(data);
              }

              
              
          /**
               * <p>
               * 文件加密
               * </p>
               * 
               * 
          @param key
               * 
          @param sourceFilePath
               * 
          @param destFilePath
               * 
          @throws Exception
               
          */

              
          public static void encryptFile(String key, String sourceFilePath, String destFilePath) throws Exception {
                  File sourceFile 
          = new File(sourceFilePath);
                  File destFile 
          = new File(destFilePath); 
                  
          if (sourceFile.exists() && sourceFile.isFile()) {
                      
          if (!destFile.getParentFile().exists()) {
                          destFile.getParentFile().mkdirs();
                      }

                      destFile.createNewFile();
                      InputStream in 
          = new FileInputStream(sourceFile);
                      OutputStream out 
          = new FileOutputStream(destFile);
                      Key k 
          = toKey(Base64Utils.decode(key));
                      Cipher cipher 
          = Cipher.getInstance(ALGORITHM);
                      cipher.init(Cipher.ENCRYPT_MODE, k);
                      CipherInputStream cin 
          = new CipherInputStream(in, cipher);
                      
          byte[] cache = new byte[CACHE_SIZE];
                      
          int nRead = 0;
                      
          while ((nRead = cin.read(cache)) != -1{
                          out.write(cache, 
          0, nRead);
                          out.flush();
                      }

                      out.close();
                      cin.close();
                      in.close();
                  }

              }

              
              
          /**
               * <p>
               * 解密
               * </p>
               * 
               * 
          @param data
               * 
          @param key
               * 
          @return
               * 
          @throws Exception
               
          */

              
          public static byte[] decrypt(byte[] data, String key) throws Exception {
                  Key k 
          = toKey(Base64Utils.decode(key));
                  Cipher cipher 
          = Cipher.getInstance(ALGORITHM);
                  cipher.init(Cipher.DECRYPT_MODE, k);
                  
          return cipher.doFinal(data);
              }

              
              
          /**
               * <p>
               * 文件解密
               * </p>
               * 
               * 
          @param key
               * 
          @param sourceFilePath
               * 
          @param destFilePath
               * 
          @throws Exception
               
          */

              
          public static void decryptFile(String key, String sourceFilePath, String destFilePath) throws Exception {
                  File sourceFile 
          = new File(sourceFilePath);
                  File destFile 
          = new File(destFilePath); 
                  
          if (sourceFile.exists() && sourceFile.isFile()) {
                      
          if (!destFile.getParentFile().exists()) {
                          destFile.getParentFile().mkdirs();
                      }

                      destFile.createNewFile();
                      InputStream in 
          = new FileInputStream(sourceFile);
                      OutputStream out 
          = new FileOutputStream(destFile);
                      Key k 
          = toKey(Base64Utils.decode(key));
                      Cipher cipher 
          = Cipher.getInstance(ALGORITHM);
                      cipher.init(Cipher.DECRYPT_MODE, k);
                      CipherOutputStream cout 
          = new CipherOutputStream(out, cipher);
                      
          byte[] cache = new byte[CACHE_SIZE];
                      
          int nRead = 0;
                      
          while ((nRead = in.read(cache)) != -1{
                          cout.write(cache, 
          0, nRead);
                          cout.flush();
                      }

                      cout.close();
                      out.close();
                      in.close();
                  }

              }


              
          /**
               * <p>
               * 轉(zhuǎn)換密鑰
               * </p>
               * 
               * 
          @param key
               * 
          @return
               * 
          @throws Exception
               
          */

              
          private static Key toKey(byte[] key) throws Exception {
                  DESKeySpec dks 
          = new DESKeySpec(key);
                  SecretKeyFactory keyFactory 
          = SecretKeyFactory.getInstance(ALGORITHM);
                  SecretKey secretKey 
          = keyFactory.generateSecret(dks);
                  
          return secretKey;
              }

              
          }


          Base64Utils.java
          package demo.security;

          import java.io.ByteArrayInputStream;
          import java.io.ByteArrayOutputStream;
          import java.io.File;
          import java.io.FileInputStream;
          import java.io.FileOutputStream;
          import java.io.InputStream;
          import java.io.OutputStream;

          import it.sauronsoftware.base64.Base64;

          /**
          * <p>
          * BASE64編碼解碼工具包
          * </p>
          * <p>
          * 依賴(lài)javabase64-1.3.1.jar
          * </p>
          *
          *
          @author IceWee
          * @date 2012-5-19
          *
          @version 1.0
          */

          public class Base64Utils {

             
          /**
               * 文件讀取緩沖區(qū)大小
              
          */

             
          private static final int CACHE_SIZE = 1024;
             
             
          /**
               * <p>
               * BASE64字符串解碼為二進(jìn)制數(shù)據(jù)
               * </p>
               *
               *
          @param base64
               *
          @return
               *
          @throws Exception
              
          */

             
          public static byte[] decode(String base64) throws Exception {
                 
          return Base64.decode(base64.getBytes());
              }

             
             
          /**
               * <p>
               * 二進(jìn)制數(shù)據(jù)編碼為BASE64字符串
               * </p>
               *
               *
          @param bytes
               *
          @return
               *
          @throws Exception
              
          */

             
          public static String encode(byte[] bytes) throws Exception {
                 
          return new String(Base64.encode(bytes));
              }

             
             
          /**
               * <p>
               * 將文件編碼為BASE64字符串
               * </p>
               * <p>
               * 大文件慎用,可能會(huì)導(dǎo)致內(nèi)存溢出
               * </p>
               *
               *
          @param filePath 文件絕對(duì)路徑
               *
          @return
               *
          @throws Exception
              
          */

             
          public static String encodeFile(String filePath) throws Exception {
                 
          byte[] bytes = fileToByte(filePath);
                 
          return encode(bytes);
              }

             
             
          /**
               * <p>
               * BASE64字符串轉(zhuǎn)回文件
               * </p>
               *
               *
          @param filePath 文件絕對(duì)路徑
               *
          @param base64 編碼字符串
               *
          @throws Exception
              
          */

             
          public static void decodeToFile(String filePath, String base64) throws Exception {
                 
          byte[] bytes = decode(base64);
                  byteArrayToFile(bytes, filePath);
              }

             
             
          /**
               * <p>
               * 文件轉(zhuǎn)換為二進(jìn)制數(shù)組
               * </p>
               *
               *
          @param filePath 文件路徑
               *
          @return
               *
          @throws Exception
              
          */

             
          public static byte[] fileToByte(String filePath) throws Exception {
                 
          byte[] data = new byte[0];
                  File file
          = new File(filePath);
                 
          if (file.exists()) {
                      FileInputStream in
          = new FileInputStream(file);
                      ByteArrayOutputStream out
          = new ByteArrayOutputStream(2048);
                     
          byte[] cache = new byte[CACHE_SIZE];
                     
          int nRead = 0;
                     
          while ((nRead = in.read(cache)) != -1) {
                          out.write(cache,
          0, nRead);
                          out.flush();
                      }

                      out.close();
                      in.close();
                      data
          = out.toByteArray();
                   }

                 
          return data;
              }

             
             
          /**
               * <p>
               * 二進(jìn)制數(shù)據(jù)寫(xiě)文件
               * </p>
               *
               *
          @param bytes 二進(jìn)制數(shù)據(jù)
               *
          @param filePath 文件生成目錄
              
          */

             
          public static void byteArrayToFile(byte[] bytes, String filePath) throws Exception {
                  InputStream in
          = new ByteArrayInputStream(bytes);  
                  File destFile
          = new File(filePath);
                 
          if (!destFile.getParentFile().exists()) {
                      destFile.getParentFile().mkdirs();
                  }

                  destFile.createNewFile();
                  OutputStream out
          = new FileOutputStream(destFile);
                 
          byte[] cache = new byte[CACHE_SIZE];
                 
          int nRead = 0;
                 
          while ((nRead = in.read(cache)) != -1) {  
                      out.write(cache,
          0, nRead);
                      out.flush();
                  }

                  out.close();
                  in.close();
              }

             
             
          }

                                          

          DESTester.java
          package demo.security;

          public class DESTester {

             
          static String key;
             
             
          static {
                 
          try {
          key
          = DESUtils.getSecretKey();
                  }
          catch (Exception e) {
                      e.printStackTrace();
                  }

              }

             
             
          public static void main(String[] args) throws Exception {
                 
          long begin = System.currentTimeMillis();
                  encryptFile();
                  decryptFile();
                  test();
                 
          long end = System.currentTimeMillis();
                  System.err.println(
          "耗時(shí):" + (end-begin)/1000 + "");
              }

             
             
          static void encryptFile() throws Exception {
                  String sourceFilePath
          = "D:/demo.mp4";
                  String destFilePath
          = "D:/demo_encrypted.mp4";
                  DESUtils.encryptFile(key, sourceFilePath, destFilePath);
              }

             
             
          static void decryptFile() throws Exception {
                  String sourceFilePath
          = "D:/demo_encrypted.mp4";
                  String destFilePath
          = "D:/demo_decrypted.mp4";
                  DESUtils.decryptFile(key, sourceFilePath, destFilePath);
              }

             
             
          static void test() throws Exception {
                  String source
          = "這是一行測(cè)試DES加密/解密的文字,你看完也等于沒(méi)看,是不是?。?!";
                  System.err.println(
          "原文:\t" + source);
                 
          byte[] inputData = source.getBytes();
                  inputData
          = DESUtils.encrypt(inputData, key);
                  System.err.println(
          "加密后:\t" + Base64Utils.encode(inputData));
                 
          byte[] outputData = DESUtils.decrypt(inputData, key);
                  String outputStr
          = new String(outputData);
                  System.err.println(
          "解密后:\t" + outputStr);
              }


          }


          Feedback

          # re: Java DES文件加密解密 javax.crypto.BadPaddingException: Given final block not properly padded  回復(fù)  更多評(píng)論   

          2012-09-04 22:09 by yaray
          str.getBytes();
          調(diào)用此方法時(shí),凡是未指定具體字符編碼的程序,均依賴(lài)于JRE所在操作系統(tǒng)的默認(rèn)編碼類(lèi)型,因此類(lèi)似的加解密程序均是不完全可靠的。解決辦法:調(diào)用此方法時(shí)指定為 UTF-8 編碼,即:str.getBytes("UTF-8");

          # re: Java DES文件加密解密 javax.crypto.BadPaddingException: Given final block not properly padded  回復(fù)  更多評(píng)論   

          2012-09-05 09:07 by IceWee
          @yaray
          感謝回復(fù),可能我系統(tǒng)上的文字都用的UTF-8編碼吧,Eclipse的編碼也用的UTF-8,所以沒(méi)有測(cè)試到這個(gè)bug。

          # re: Java DES文件加密解密 javax.crypto.BadPaddingException: Given final block not properly padded  回復(fù)  更多評(píng)論   

          2013-01-10 20:34 by free4wp
          SecureRandom 實(shí)現(xiàn)完全隨操作系統(tǒng)本身的內(nèi)部狀態(tài),除非調(diào)用方在調(diào)用 getInstance 方法之后又調(diào)用了 setSeed 方法;該實(shí)現(xiàn)在 windows 上每次生成的 key 都相同,但是在 solaris 或部分 linux 系統(tǒng)上則不同。
          正確的解決方法:
          http://free4wp.com/%e8%a7%a3%e5%86%b3linux%e6%93%8d%e4%bd%9c%e7%b3%bb%e7%bb%9f%e4%b8%8baes%e8%a7%a3%e5%af%86%e5%a4%b1%e8%b4%a5%e7%9a%84%e9%97%ae%e9%a2%98.html
          主站蜘蛛池模板: 长岛县| 恩施市| 太湖县| 长白| 汕尾市| 九龙城区| 紫金县| 毕节市| 乌鲁木齐市| 白山市| 望奎县| 富顺县| 博湖县| 申扎县| 葵青区| 军事| 玉林市| 石台县| 禄劝| 韶关市| 博爱县| 木兰县| 岐山县| 潜山县| 施甸县| 太湖县| 若尔盖县| 阿合奇县| 同心县| 呼伦贝尔市| 昆明市| 财经| 定兴县| 柳河县| 永嘉县| 肥西县| 涟源市| 濮阳县| 宜兴市| 孟村| 普格县|