|
在各个客户服务器上运行好好的PBE加解密程序突然在一个用AIX服务器的客户那报错了,错误信息为:Given final block not properly padded,从异常堆栈发现,其它服务器的jdk 中的加密提供者都是 sun的,而这台aix服务jdk解密提供者为 ibm的!!!
看这意思貌似是填充相关的错误,首先反应是google一下,== 谷歌已经没了,那百度一下。
网上说的有几种情况,
1、加密代码问题,导致报错;但我这段代码可以正常运行,只是在不同加解密提供商下导致的错误,排除
2、说不同平台的SecureRandom random=new SecureRandom(); 实现不同,需要使用程序指定的方式生成随机数。我看了下自己的加密算法,貌似解密的时候,并没有用到此随机数,只有在加密的时候用它生成salt. 所以,半信半疑的排除了
无奈之下,我将算法 由 PBEWithSHA1AndDESede 修改为:PBEWithMD5AndDES 进行测试,结果居然能正常运行,可以想象,ibm提供的pbe解密应该是没有提供 PBEWithSHA1AndDESede 这种算法。如果提供了,那应该就能正常解密,毕竟pbe是标准对称加密算法,所有算法提供者提供的算法计算结果应该都一样,变的只是密码而已。
附上代码:
private static final String PBECODER_PASSWORD = "www.lyjilu.com";
/**
* JAVA6支持以下任意一种算法
* PBEWITHMD5ANDDES
* PBEWithMD5AndDES
* PBEWITHMD5ANDTRIPLEDES
* PBEWITHSHAANDDESEDE
* PBEWITHSHA1ANDRC2_40
* PBKDF2WITHHMACSHA1
* */
public static final String ALGORITHM="PBEWithMD5AndDES";
/**
* 迭代次数
* */
public static final int ITERATION_COUNT=100;
/**
* 盐初始化
* 盐长度必须为8字节
* @return byte[] 盐
* */
public static byte[] initSalt() throws Exception{
//实例化安全随机数
SecureRandom random=new SecureRandom();
//产出盐
return random.generateSeed(8);
}
/**
* 转换密钥
* @param password 密码
* @return Key 密钥
* */
private static Key toKey(String password) throws Exception{
//密钥转换
PBEKeySpec keySpec=new PBEKeySpec(password.toCharArray());
//实例化
SecretKeyFactory keyFactory=SecretKeyFactory.getInstance(ALGORITHM);
//生成密钥
SecretKey secretKey=keyFactory.generateSecret(keySpec);
return secretKey;
}
/**
* 加密
* @param data 待加密数据
* @param password 密码
* @param salt 盐
* @return byte[] 加密数据
*
* */
public static byte[] encrypt(byte[] data,String password,byte[] salt) throws Exception{
//转换密钥
Key key=toKey(password);
//实例化PBE参数材料
PBEParameterSpec paramSpec=new PBEParameterSpec(salt,ITERATION_COUNT);
//实例化
Cipher cipher=Cipher.getInstance(ALGORITHM);
//初始化
cipher.init(Cipher.ENCRYPT_MODE, key,paramSpec);
//执行操作
return cipher.doFinal(data);
}
public static byte[] encrypt(byte[] data,byte[] salt) throws Exception{
String pwd = PBECODER_PASSWORD;
return encrypt(data,pwd, salt);
}
/**
* 解密
* @param data 待解密数据
* @param password 密码
* @param salt 盐
* @return byte[] 解密数据
*
* */
public static byte[] decrypt(byte[] data,String password,byte[] salt) throws Exception{
//转换密钥
Key key=toKey(password);
//实例化PBE参数材料
PBEParameterSpec paramSpec=new PBEParameterSpec(salt,ITERATION_COUNT);
//实例化
Cipher cipher=Cipher.getInstance(ALGORITHM);
//初始化
cipher.init(Cipher.DECRYPT_MODE, key,paramSpec);
//执行操作
return cipher.doFinal(data);
}
public static byte[] decrypt(byte[] data,byte[] salt) throws Exception{
return decrypt(data, PBECODER_PASSWORD, salt);
}
|
|
|