Java AES加密/解密始终返回相同的内容
我为AES加密和解密编写了一个小测试用例。计划是从文件中读取一些文本,用密钥加密,然后再次解密。现在的问题是,文本总是相同的,错误的密码不会导致无法读取的文本 代码中的问题在哪里,或者我犯了根本性的错误 Main.javaJava AES加密/解密始终返回相同的内容,java,encryption,cryptography,aes,Java,Encryption,Cryptography,Aes,我为AES加密和解密编写了一个小测试用例。计划是从文件中读取一些文本,用密钥加密,然后再次解密。现在的问题是,文本总是相同的,错误的密码不会导致无法读取的文本 代码中的问题在哪里,或者我犯了根本性的错误 Main.java import javax.crypto.spec.SecretKeySpec; public class Main { public static void main(String[] args) throws Exception { new Mai
import javax.crypto.spec.SecretKeySpec;
public class Main {
public static void main(String[] args) throws Exception {
new Main();
}
public Main() throws Exception {
Reader reader = new Reader();
String text = reader.readFile("/home/benjamin/Test.txt");
System.out.println("Original text before encryption: " + text);
// User A verschlüsselt und speichert ab
Crypto crypto = new Crypto();
SecretKeySpec secretkey = crypto.generateSecretKey("123456aA");
byte[] encryptedtext = crypto.encrypt(text, secretkey);
// User B lädt Datei und kennt das Passwort
Crypto crypto2 = new Crypto();
SecretKeySpec secretkey2 = crypto2.generateSecretKey("1kkk23456aAjbhhjbhjb");
byte[] decryptedtext = crypto2.decrypt(encryptedtext, secretkey2);
System.out.println("Original text after encryption: " + new String(decryptedtext, "UTF-8"));
}
}
Crypto.java
import java.security.MessageDigest;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Crypto {
public SecretKeySpec generateSecretKey(String password) throws Exception {
MessageDigest shahash = MessageDigest.getInstance("SHA-1");
byte[] key = shahash.digest();
key = Arrays.copyOf(key, 16);
return new SecretKeySpec(key, "AES");
}
public byte[] encrypt(String text, SecretKeySpec secretkey) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretkey);
return cipher.doFinal(text.getBytes());
}
public byte[] decrypt(byte[] encryptedtext, SecretKeySpec secretkey) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretkey);
return cipher.doFinal(encryptedtext);
}
}
这就是问题所在:
public SecretKeySpec generateSecretKey(String password) throws Exception {
MessageDigest shahash = MessageDigest.getInstance("SHA-1");
byte[] key = shahash.digest();
key = Arrays.copyOf(key, 16);
return new SecretKeySpec(key, "AES");
}
您在generateScretKey
中的任何位置都不使用password
,因此每次都会创建相同的密钥
如果将其更改为:
public SecretKeySpec generateSecretKey(String password) throws Exception {
MessageDigest shahash = MessageDigest.getInstance("SHA-1");
byte[] key = shahash.digest(password.getBytes("UTF-8"));
key = Arrays.copyOf(key, 16);
return new SecretKeySpec(key, "AES");
}
然后,当输入错误的密码时,它将按预期失败。这并不一定意味着这是创建密钥的最佳方式,也不意味着其他任何加密代码都是合适的,但我没有足够的经验对此发表评论。这就是问题所在:
public SecretKeySpec generateSecretKey(String password) throws Exception {
MessageDigest shahash = MessageDigest.getInstance("SHA-1");
byte[] key = shahash.digest();
key = Arrays.copyOf(key, 16);
return new SecretKeySpec(key, "AES");
}
您在generateScretKey
中的任何位置都不使用password
,因此每次都会创建相同的密钥
如果将其更改为:
public SecretKeySpec generateSecretKey(String password) throws Exception {
MessageDigest shahash = MessageDigest.getInstance("SHA-1");
byte[] key = shahash.digest(password.getBytes("UTF-8"));
key = Arrays.copyOf(key, 16);
return new SecretKeySpec(key, "AES");
}
然后,当输入错误的密码时,它将按预期失败。这并不一定意味着这是创建密钥的最佳方式,也不意味着其他任何加密代码都是合适的,但我没有足够的经验对此发表评论。
generateScretKey
方法被破坏了。它根据空字符串的摘要生成密钥–忽略password
参数
还有其他问题。ECB模式不安全。这里的密钥派生非常弱。取决于平台,默认字符编码不是一个好主意。generateScretKey方法被破坏。它根据空字符串的摘要生成密钥–忽略
password
参数
还有其他问题。ECB模式不安全。这里的密钥派生非常弱。根据平台的不同,默认字符编码不是一个好主意。应使用适当的密钥派生函数,如PBKDF2、bcrypt或scrypt。此外,CBC而不是欧洲央行。最后,所有字符串-字节数组转换都使用UTF-8。@ntoskrnl:我相信你的话:)(我知道我在安全性方面的限制…)应该使用适当的密钥派生函数,如PBKDF2、bcrypt或scrypt。此外,CBC而不是欧洲央行。最后,所有字符串-字节数组转换都使用UTF-8。@ntoskrnl:我相信你的话:)(我知道我在安全性方面的极限…)