最近做項目,需要加密Android客戶端的一些sql語句,我當時使用的是DES加密的,結果加密出現了
- javax.crypto.BadPaddingException: Given final block not properly padded
這樣的錯誤,要不就是出現亂碼的問題,很糾結!當時查了一些資料,就有可能是密鑰的問題或者編碼的問題,檢查了發現,密鑰正確的,就是在創建Key 的時候,得到的byte[]數組有一些處理的,具體完整的代碼如下:
- package com.spring.sky.util;
-
- import java.io.BufferedReader;
- import java.io.BufferedWriter;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.io.OutputStream;
- import java.security.Key;
-
- import javax.crypto.Cipher;
- import javax.crypto.CipherInputStream;
- import javax.crypto.spec.SecretKeySpec;
-
- import org.apache.http.entity.InputStreamEntity;
-
- /***
- * DES文件加密&解密 <br>
- * 可以實現android和window的文件互通
- * @author spring.sky
- * Email:[email protected]
- * QQ:840950105
- *
- */
- public class FileDES {
- /**加密解密的key*/
- private Key mKey;
- /**解密的密碼*/
- private Cipher mDecryptCipher;
- /**加密的密碼*/
- private Cipher mEncryptCipher;
- public FileDES(String key) throws Exception
- {
- initKey(key);
- initCipher();
- }
-
- /**
- * 創建一個加密解密的key
- * @param keyRule
- */
- public void initKey(String keyRule) {
- byte[] keyByte = keyRule.getBytes();
- // 創建一個空的八位數組,默認情況下為0
- byte[] byteTemp = new byte[8];
- // 將用戶指定的規則轉換成八位數組
- for (int i = 0; i < byteTemp.length && i < keyByte.length; i++) {
- byteTemp[i] = keyByte[i];
- }
- mKey = new SecretKeySpec(byteTemp, "DES");
- }
-
- /***
- * 初始化加載密碼
- * @throws Exception
- */
- private void initCipher() throws Exception
- {
- mEncryptCipher = Cipher.getInstance("DES");
- mEncryptCipher.init(Cipher.ENCRYPT_MODE, mKey);
-
- mDecryptCipher = Cipher.getInstance("DES");
- mDecryptCipher.init(Cipher.DECRYPT_MODE, mKey);
- }
-
- /**
- * 加密文件
- * @param in
- * @param savePath 加密後保存的位置
- */
- public void doEncryptFile(InputStream in,String savePath)
- {
- if(in==null)
- {
- System.out.println("inputstream is null");
- return;
- }
- try {
- CipherInputStream cin = new CipherInputStream(in, mEncryptCipher);
- OutputStream os = new FileOutputStream(savePath);
- byte[] bytes = new byte[1024];
- int len = -1;
- while((len=cin.read(bytes))>0)
- {
- os.write(bytes, 0, len);
- os.flush();
- }
- os.close();
- cin.close();
- in.close();
- System.out.println("加密成功");
- } catch (Exception e) {
- System.out.println("加密失敗");
- e.printStackTrace();
- }
- }
-
- /**
- * 加密文件
- * @param filePath 需要加密的文件路徑
- * @param savePath 加密後保存的位置
- * @throws FileNotFoundException
- */
- public void doEncryptFile(String filePath,String savePath) throws FileNotFoundException
- {
- doEncryptFile(new FileInputStream(filePath), savePath);
- }
-
-
- /**
- * 解密文件
- * @param in
- */
- public void doDecryptFile(InputStream in)
- {
- if(in==null)
- {
- System.out.println("inputstream is null");
- return;
- }
- try {
- CipherInputStream cin = new CipherInputStream(in, mDecryptCipher);
- BufferedReader reader = new BufferedReader(new InputStreamReader(cin)) ;
- String line = null;
- while((line=reader.readLine())!=null)
- {
- System.out.println(line);
- }
- reader.close();
- cin.close();
- in.close();
- System.out.println("解密成功");
- } catch (Exception e) {
- System.out.println("解密失敗");
- e.printStackTrace();
- }
- }
- /**
- * 解密文件
- * @param filePath 文件路徑
- * @throws Exception
- */
- public void doDecryptFile(String filePath) throws Exception
- {
- doDecryptFile(new FileInputStream(filePath));
- }
-
-
- public static void main(String[] args)throws Exception {
- FileDES fileDES = new FileDES("spring.sky");
- fileDES.doEncryptFile("d:/a.txt", "d:/b"); //加密
- fileDES.doDecryptFile("d:/b"); //解密
- }
-
- }
上面的代碼,我分別在android 1.6和java平台上面測試通過了,沒任何問題的,只是根據不同的需求做一下封裝,希望對大家有幫忙,讓大家少走彎路!
更多Android相關信息見Android 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=11