System.out.println(DesUtil.decrypt(“/s=”, DesUtil.KEY));
}
}
就是这个人,main方法加解密是不会报错, 而嵌套到URL中就报错了,细心的我最后发现别人转码后有一个“/”, 而这个人转了之后却又两个“/”,于是我想到了URLEncoder,加上之后,确实不报错了,而是后台出来了个大大的bug, 就是这个“Given final block not properly padded”,所以不得不去网上寻找解药。
以下是网上解决方案,非本人原创,特此声明!
仔细分析一下,不难发现,该异常是在解密的时候抛出的,加密的方法没有问题。
但是两个方法的唯一差别是Cipher对象的模式不一样,这就排除了程序写错的可能性。再看一下异常的揭示信息,大概的意思是:提供的字块不符合填补的。什么意思???原来在用DES加密的时候,最后一位长度不足64的,它会自动填补到64,那么在我们进行字节数组到字串的转化过程中,可以把它填补的不可见字符改变了,所以引发系统抛出异常。问题找到,怎么解决呢?大家还记得邮件传输通常会把一些信息编码保存,对了,就是Base64,那样保证了信息的完整性,所以我们就是利用一下下了。为了方便使用,我们再写一个新的方法封装一下原来的方法:
public static String DataEncrypt(String str,byte[] key){
String encrypt = null;
try{
byte[] ret = encode(str.getBytes(“UTF-8”),key);
encrypt = new String(Base64.encode(ret));
}catch(Exception e){
System.out.print(e);
encrypt = str;
}
return encrypt;
}
public static String DataDecrypt(String str,byte[] key){
String decrypt = null;
try{
byte[] ret = decode(Base64.decode(str),key);
decrypt = new String(ret,”UTF-8”);
}catch(Exception e){
System.out.print(e);
decrypt = str;
}
return decrypt;
}
我们把方法的参数改成了字串,但是为什么要用UTF-8呢?不指定它的字节格式不行吗?大家知道,UTF-8是国际通用的字符编码,用它传输任何字串都不会有问题,通过它也可以很完美的解决J2EE的中文问题!所以我们最好用UTF-8编码,以减少不必要的麻烦。
结合上述方法,我的DesUtil修改版诞生了!
package com.kwp.main.util.security;
import java.io.IOException;
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.xml.internal.security.utils.Base64;
public class DesUtil {
private final static String DES = “DES”;
public final static String KEY = “EA22DAB57022E2560A376749E3408196A9E287D800E068E5”;
/**
-
Description 根据键值进行加密
-
@param data
-
@param key 加密键byte数组
-
@return
-
@throws Exception
*/
private static byte[] encrypt(byte[] data, byte[] key) throws Exception {
// 生成一个可信任的随机数源
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(data);
}
/**
-
Description 根据键值进行解密
-
@param data
-
@param key 加密键byte数组
-
@return
-
@throws Exception
*/
private static byte[] decrypt(byte[] data, byte[] key) throws Exception {
// 生成一个可信任的随机数源
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(data);
}
/**
-
Description 根据键值进行加密
-
@param data
-
@param key 加密键byte数组
-
@return
-
@throws Exception
*/
public static String encrypt(String data, String key) throws Exception {
if (data == null) return null;
String strs = null;
try{
byte[] ret = encrypt(data.getBytes(“UTF-8”), key.getBytes(“UTF-8”));
strs = new String(Base64.encode(ret));
}catch(Exception e){
System.out.print(e);
strs = data;
}
System.out .println(“加密后:” + strs);
return strs;
}
/**
-
Description 根据键值进行解密
-
@param data
-
@param key 加密键byte数组
-
@return
-
@throws IOException
-
@throws Exception
*/
public static String decrypt(String data, String key) throws IOException, Exception {
if (data == null) return null;
String strs = null;
try{
byte[] ret = decrypt(Base64.decode(data), key.getBytes(“UTF-8”));
strs = new String(ret,“UTF-8”);
}catch(Exception e){
System.out.print(e);
strs = data;
}
System.out.println(“解密后:” + strs);
return strs;
}
public static void main(String[] args)throws Exception{
//加密
// System.out.println(DesUtil.encrypt(“liujianyong”, “elink!@#$%”));
文末
篇幅有限没有列举更多的前端面试题,小编把整理的前端大厂面试题PDF分享出来,一共有269页