带有随机盐的Java AES给出了一个错误;javax.crypto.BadPaddingException:给定的最后一个块未正确填充“;
我正在尝试使用自动生成的Salt运行以下AES加密。但当我尝试解密时,它会抛出一条错误消息。主要的想法是 我有一个获取用户名和密码的窗口。然后,它将使用该密码加密数据。以及当用户想要查看它时。他用密码解密 代码带有随机盐的Java AES给出了一个错误;javax.crypto.BadPaddingException:给定的最后一个块未正确填充“;,java,encryption,Java,Encryption,我正在尝试使用自动生成的Salt运行以下AES加密。但当我尝试解密时,它会抛出一条错误消息。主要的想法是 我有一个获取用户名和密码的窗口。然后,它将使用该密码加密数据。以及当用户想要查看它时。他用密码解密 代码 import org.apache.commons.codec.binary.Base64; public class Decrypts { private static final String password = "haasd"; private static f
import org.apache.commons.codec.binary.Base64;
public class Decrypts {
private static final String password = "haasd";
private static final String ALGO = "AES";
public static String encrypt(String Data) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(Data.getBytes());
byte[] encryptedValue = new Base64().encode(encVal);
String ency = new String(encryptedValue);
return ency;
}
@SuppressWarnings("static-access")
public static String decrypt(String encryptedData) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new Base64().decodeBase64(encryptedData);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
private static Key generateKey() throws Exception {
try {
String salt;
int pswdIterations = 65536;
int keySize = 256;
salt = generateSalt();
byte[] saltBytes = salt.getBytes("UTF-8");
SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes,
pswdIterations, keySize);
SecretKey secretKey = factory.generateSecret(spec);
Key key = new SecretKeySpec(secretKey.getEncoded(), "AES");
return key;
} catch (Exception e) {
System.out.println(e);
}
return null;
}
public static String generateSalt() {
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);
String s = new String(bytes);
return s;
}
}
public class Decrypts {
private static final String password = "haasd";
private static final String ALGO = "AES";
public static String encrypt(String Data) throws Exception {
String SALT = generateSalt();
byte[] saltBytes = SALT.getBytes("UTF-8");
System.out.println("Saltbytes ; " + saltBytes);
SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes,
65536, 256);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, secret);
byte[] encVal = c.doFinal(Data.getBytes());
byte[] encryptedValue = new Base64().encode(encVal);
String ency = new String(encryptedValue);
return ency;
}
@SuppressWarnings("static-access")
public static String decrypt(String encryptedData) throws Exception {
String SALT = generateSalt();
byte[] saltBytes = SALT.getBytes("UTF-8");
System.out.println("Saltbytes ; " + saltBytes);
SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes,
65536, 256);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, secret);
byte[] decordedValue = new Base64().decodeBase64(encryptedData);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
public static String generateSalt() {
SecureRandom random = new SecureRandom(password.getBytes());
byte bytes[] = new byte[120];
random.nextBytes(bytes);
String s = new String(bytes);
System.out.println("Salt ; " + s);
return s;
}
}
更新代码
import org.apache.commons.codec.binary.Base64;
public class Decrypts {
private static final String password = "haasd";
private static final String ALGO = "AES";
public static String encrypt(String Data) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = c.doFinal(Data.getBytes());
byte[] encryptedValue = new Base64().encode(encVal);
String ency = new String(encryptedValue);
return ency;
}
@SuppressWarnings("static-access")
public static String decrypt(String encryptedData) throws Exception {
Key key = generateKey();
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new Base64().decodeBase64(encryptedData);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
private static Key generateKey() throws Exception {
try {
String salt;
int pswdIterations = 65536;
int keySize = 256;
salt = generateSalt();
byte[] saltBytes = salt.getBytes("UTF-8");
SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes,
pswdIterations, keySize);
SecretKey secretKey = factory.generateSecret(spec);
Key key = new SecretKeySpec(secretKey.getEncoded(), "AES");
return key;
} catch (Exception e) {
System.out.println(e);
}
return null;
}
public static String generateSalt() {
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);
String s = new String(bytes);
return s;
}
}
public class Decrypts {
private static final String password = "haasd";
private static final String ALGO = "AES";
public static String encrypt(String Data) throws Exception {
String SALT = generateSalt();
byte[] saltBytes = SALT.getBytes("UTF-8");
System.out.println("Saltbytes ; " + saltBytes);
SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes,
65536, 256);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, secret);
byte[] encVal = c.doFinal(Data.getBytes());
byte[] encryptedValue = new Base64().encode(encVal);
String ency = new String(encryptedValue);
return ency;
}
@SuppressWarnings("static-access")
public static String decrypt(String encryptedData) throws Exception {
String SALT = generateSalt();
byte[] saltBytes = SALT.getBytes("UTF-8");
System.out.println("Saltbytes ; " + saltBytes);
SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), saltBytes,
65536, 256);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.DECRYPT_MODE, secret);
byte[] decordedValue = new Base64().decodeBase64(encryptedData);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
public static String generateSalt() {
SecureRandom random = new SecureRandom(password.getBytes());
byte bytes[] = new byte[120];
random.nextBytes(bytes);
String s = new String(bytes);
System.out.println("Salt ; " + s);
return s;
}
}
在
encrypt()
和decrypt()
中生成随机salt,salt生成将在两种方法中给出不同的salt,因此,如果最后一个块没有正确填充,您将得到错误
事实上,您应该只使用一种您指定的普通盐(固定盐)或随机生成的盐。让我们为它定义一个类变量
private static final String password = "haasd";
private static final String ALGO = "AES";
private static final String SALT = generateSalt(); //generate salt once
然后在您的generateKey()
中,不要再次生成salt,只需使用类成员salt
//byte[] saltBytes = salt.getBytes("UTF-8");
byte[] saltBytes = SALT.getBytes("UTF-8"); //using class member SALT
另一种方法是在加密和解密方法中接受用户输入的密码作为参数。然后使用该密码生成salt,如下所示
public static String generateSalt(String password) {
SecureRandom random = new SecureRandom(password.getBytes());
...
}
如果我这样做了,如果我加密同一个单词,不会给出相同的加密值吗?因为密码和salt都是一样的?因为我不会同时解密它。它将存储加密的值,当用户只需要时,它将解密。那么我需要指定salt,对吗?@checkmate基本上是的,在您的情况下,生成的salt对于一对work encrypt()和decrypt()必须是相同的。如果一个单词用salta
加密,则该加密文本需要用相同的salta
解密。因此,您需要维护生成的salt(在加密时),以备将来使用(在解密时)。无论是在文件系统中保存还是以任何存储库方式保存。嗯,还有其他方法可以使用随机salt进行加密和解密吗?如果有,请在加密和解密中接受用户输入的密码作为arg,并使用固定salt。然后在new PBEKeySpec()
中使用该密码。Hy,非常感谢您抽出时间。尽管如此,如果密码相同,我仍然会得到相同的加密密钥。我检查了一下,盐和盐没有什么不同。和键总是一样的。检查我编辑的答案。