java DES 加密解密算法及报错 Given final block not properly padded

解密的时候报错: 

javax.crypto.BadPaddingException:   Given   final   block   not   properly   padded 

该异常是在解密的时候抛出的,加密的方法没有问题。  

但是两个方法的唯一差别是Cipher对象的模式不一样,这就排除了程序写错的可能性。再看一下异常的揭示信息,大概的意思是:提供的字块不符合填补的。原来在用DES加密的时候,最后一位长度不足64的,它会自动填补到64,那么在我们进行字节数组到字串的转化过程中,可以把它填补的不可见字符改变了,所以引发系统抛出异常。大家还记得邮件传输通常会把一些信息编码保存,就是Base64,那样保证了信息的完整性,所以我们就是利用一下下了。为了方便使用,再写一个新的方法封装一下原来的方法:  1.  DataDecrypt   2.  DataEncrypt

加密:

import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;


import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
public class DescryptCoder {
      
  private final static String DES = "DES";
      
  /**
   *
   * @param src 数据源
   * @param key 密钥,长度必须是8的倍数
   * @return
   * @throws Exception
   */
  public static byte[] decrypt(byte[] src, byte[] key) throws Exception {
    // DES算法要求有一个可信任的随机数源
    SecureRandom sr = new SecureRandom();
    // 从原始密匙数据创建一个DESKeySpec对象
    DESKeySpec dks = new DESKeySpec(key);
    // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成一个SecretKey对象
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
    SecretKey securekey = keyFactory.generateSecret(dks);
    // Cipher对象实际完成解密操作
    Cipher cipher = Cipher.getInstance(DES);
    // 用密匙初始化Cipher对象
    cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
        
    // 正式执行解密操作
    return cipher.doFinal(src);
  }
      
  public final static String decrypt(String data, String key) {
    try {
    //这里就没走
      return new String(decrypt(String2byte(data.getBytes()), key.getBytes()));
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
      
  public static byte[] String2byte(byte[] b) {
    if ((b.length % 2) != 0)
      throw new IllegalArgumentException("长度不是偶数");
    byte[] b2 = new byte[b.length / 2];
    for (int n = 0; n < b.length; n += 2) {
      String item = new String(b, n, 2);
      b2[n / 2] = (byte) Integer.parseInt(item, 16);
    }
    return b2;
  }
  public static String DataDecrypt(String str,byte[] key){  
 String decrypt = null;  
 try{  
 byte[] ret = decrypt(Base64.decode(str),key);  
 decrypt = new String(ret,"UTF-8");  
 }catch(Exception e){  
 System.out.print(e);  
 decrypt = str;  
 }  
 return decrypt;  


 } 
  public static void main(String[] args){
    String desencryptString = decrypt("B00542E93695F4CFCE34FC4393C2F4BF","test中英文杂七烂八混搭@123654{");
    System.out.println(desencryptString);
  }
  //输出:is张三丰
}




解密:


import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;


import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
public class EncryptCoder {
            
  private final static String DES = "DES";
            
  public static byte[] encrypt(byte[] src, byte[] key) throws Exception {
    // DES算法要求有一个可信任的随机数源
    SecureRandom sr = new SecureRandom();
    // 从原始密匙数据创建DESKeySpec对象
    DESKeySpec dks = new DESKeySpec(key);
    // 创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
    SecretKey securekey = keyFactory.generateSecret(dks);
    // Cipher对象实际完成加密操作
    Cipher cipher = Cipher.getInstance(DES);
    // 用密匙初始化Cipher对象
    cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
    // 正式执行加密操作
    return cipher.doFinal(src);
  }
  /**
  *
  * @param password 密码
  * @param key 加密字符串
  * @return
  */
 public final static String encrypt(String password, String key) {
   try {
     return byte2String(encrypt(password.getBytes(), key.getBytes()));
   } catch (Exception e) {
   }
   return null;
 }
           
 public static String byte2String(byte[] b) {
   String hs = "";
   String stmp = "";
   for (int n = 0; n < b.length; n++) {
     stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
     if (stmp.length() == 1)
       hs = hs + "0" + stmp;
     else
       hs = hs + stmp;
   }
   return hs.toUpperCase();
 }   
 public static String DataEncrypt(String str,byte[] key){  


 String encrypt = null;  
 try{  
 byte[] ret = encrypt(str.getBytes("UTF-8"),key);  
 encrypt = new String(Base64.encode(ret));  
 }catch(Exception e){  
 System.out.print(e);  
 encrypt = str;  
 }  
 return encrypt;  
 }  
 public static void main(String[] args){
   String encryptString = EncryptCoder.encrypt("is张三丰","test中英文杂七烂八混搭@123654{");
   System.out.println("加密后:"+encryptString);
 } 
 //输出:B00542E93695F4CFCE34FC4393C2F4BF   
}


你可能感兴趣的:(Java,web技术)