我正在从文件中检索文本密码作为输入,然后对其应用AES加密,然后对其进行解密。 当我第一次这样做的时候,它每5次中有4次运行正常(加密解密成功)但是1次,它抛出BadPaddingException。以下是我写的:
//ABCD is class name
public static void enc(String fileName, String pwd) {
try {
Properties prop = new Properties();
InputStream input = ABCD.class.getClassLoader().getResourceAsStream(fileName);
prop.load(input);
input.close();
URL url = ABCD.class.getClassLoader().getResource(fileName);
FileOutputStream outputStream = new FileOutputStream(url.getPath());
KeyGenerator key = KeyGenerator.getInstance("AES");
key.init(128);
SecretKey aesKey = key.generateKey();
String newkey = new String(Base64.encode(aesKey.getEncoded()).getBytes("UTF-8"));
Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
aesCipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] clear = pwd.getBytes("UTF-8");
byte[] cipher = aesCipher.doFinal(clear);
String encPwd = new String(cipher);
prop.setProperty("password", encPwd);
prop.setProperty("secKey", newkey);
prop.store(outputStream, null);
outputStream.close();
} catch (Exception e) {
System.out.println(e);
}
}
public static String dec(Properties prop, String fileName) {
String decPwd = ABCD.map.get(fileName);
try {
String newkey = prop.getProperty("secKey");
StringBuilder pwd;
byte[] newkeybuff = Base64.decode(newkey.getBytes("UTF-8"));
SecretKey key = new SecretKeySpec(newkeyuff, "AES");
Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
aesCipher.init(Cipher.DECRYPT_MODE, key);
pwd = new StringBuilder(prop.getProperty("password"));
byte[] cipher = aesCipher.doFinal(pwd.toString().getBytes());
decPwd = new String(cipher);
} catch (Exception e) {
System.out.println(e);
}
ABCD.map.put(fileName, decPwd);
return decPwd;
}
我需要解决这个问题。在某处,我读到BadPaddingExcpetion发生在使用String完成的操作之后,代替实际应该使用的字节。因此,我将代码更改为以下内容:
public static void enc(String fileName, String pwd) {
try {
Properties prop = new Properties();
InputStream input = ABCD.class.getClassLoader().getResourceAsStream(fileName);
prop.load(input);
input.close();
URL url = ABCD.class.getClassLoader().getResource(fileName);
FileOutputStream outputStream = new FileOutputStream(url.getPath());
KeyGenerator key = KeyGenerator.getInstance("AES");
key.init(128);
SecretKey aesKey = key.generateKey();
byte[] newkey=(Base64.encode(aesKey.getEncoded())).getBytes("UTF-8");
Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
aesCipher.init(Cipher.ENCRYPT_MODE, aesKey,new IvParameterSpec(new byte[16]));
byte[] clear = pwd.getBytes("UTF-8");
byte[] cipher = aesCipher.doFinal(clear);
prop.setProperty("password", Arrays.toString(cipher));
prop.setProperty("secKey", Arrays.toString(newkey));
prop.store(outputStream, null);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
System.out.println(e);
}
}
public static String dec(Properties prop, String fileName) {
String decPwd = ABCD.map.get(fileName);
try {
byte[] newkey=prop.getProperty("secKey").getBytes("UTF-8");
byte[] pwd;
byte[] newkeybuff = Base64.decode(newkey);
SecretKeySpec key = new SecretKeySpec(newkeybuff, "AES");
Cipher aesCipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
aesCipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(new byte[16]));
pwd = prop.getProperty("password").getBytes();
byte[] cipher = aesCipher.doFinal(pwd);
decPwd=new String(cipher);
System.out.println("Decrypted pwd " + decPwd);
}
catch (Exception e) {
System.out.println(e);
}
ABCD.map.put(fileName, decPwd);
return decPwd;
}
现在,我收到了InvalidKeyException。这次,我读到密钥的大小应该是16个字节。但我不知道如何应用这个。需要修复此问题!
答案 0 :(得分:0)
您应该检查您的IV(初始化向量),加密和解密必须相同。
答案 1 :(得分:0)
填充错误通常意味着解密失败。
检查密钥是全长(16,24或32字节),IV是全长(16字节)。如果密钥或IV是短的,它将填充“东西”,并且该人不一致,没有这种填充的标准。
getBytes("UTF-8")
可能会返回不同的字节长度,具体取决于使用的字符。
对于IV使用new IvParameterSpec(new byte[16])
不正确,IV应该是随机字节。处理IV的一种常用方法是在加密时创建一个随机IV并将其添加到加密数据中,它不需要是秘密的,并且通过预先设置它将可用于解密。