最近做项目,需要加密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:vipa1888@163.com * 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平台上面测试通过了,没任何问题的,只是根据不同的需求做一下封装,希望对大家有帮忙,让大家少走弯路!