我的应用程序在 Windows 中运行,但在 Linux 中失败Given final block not properly padded
例外。
配置:
- JDK版本:1.6
- Windows:版本 7
- Linux:CentOS 5.8 64位
我的代码如下:
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class SecurityKey {
private static Key key = null;
private static String encode = "UTF-8";
private static String cipherKey = "DES/ECB/PKCS5Padding";
static {
try {
KeyGenerator generator = KeyGenerator.getInstance("DES");
String seedStr = "test";
generator.init(new SecureRandom(seedStr.getBytes()));
key = generator.generateKey();
} catch(Exception e) {
}
}
// SecurityKey.decodeKey("password")
public static String decodeKey(String str) throws Exception {
if(str == null)
return str;
Cipher cipher = null;
byte[] raw = null;
BASE64Decoder decoder = new BASE64Decoder();
String result = null;
cipher = Cipher.getInstance(cipherKey);
cipher.init(Cipher.DECRYPT_MODE, key);
raw = decoder.decodeBuffer(str);
byte[] stringBytes = null;
stringBytes = cipher.doFinal(raw); // Exception!!!!
result = new String(stringBytes, encode);
return result;
}
}
在行:
ciper.doFilnal(raw);
抛出以下异常:
javax.crypto.BadPaddingException: Given final block not properly padded
我该如何解决这个问题?
答案在于这样一个事实:SecureRandom
对于特定的运行时间,播种可能会有所不同。大多数时候你会得到"SHA1PRNG"
,不会立即播种。相反,您可以致电setSeed()
在请求任何随机之前,在这种情况下,种子被用作唯一的熵源。在这种情况下,您的密钥将始终相同。
问题是没有定义哪个SecureRandom
被返回。您可能会得到一个完全不同的、特定于平台的实现,但上述情况并不成立。如果 Sun 提供程序的优先级较高,您可能无法获得其中一个提供程序。
然后是种子的问题。种子使用平台默认编码seedStr
调用期间的变量getBytes()
。由于编码可能不同,种子也可能不同,因此结果也会不同。
尝试使用PBKDF2等函数来代替密钥导出; stackoverflow 上有足够的关于如何进行的信息。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)