0

我为 AES 加密和解密编写了一个小测试用例。计划是从文件中读取一些文本,用密钥对其进行加密并再次解密。现在的问题是,文本总是相同的,错误的密码不会导致无法读取的文本。

代码中的问题在哪里,还是我犯了一个根本性错误?

主.java

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"));
    }
}

加密.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);
    }
}
4

2 回答 2

3

这就是问题:

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");
}

您不会password在 中的任何地方使用generateSecretKey,因此它每次都会创建相同的密钥...

如果您将其更改为:

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");
}

那么当输入错误的密码时,它将按预期失败。这并不一定意味着它是创建密钥的最佳方式,或者其他任何加密代码都是合适的,但我没有足够的经验对此发表评论。

于 2013-08-26T08:58:44.273 回答
0

generateSecretKey方法坏了。它根据空字符串的摘要生成密钥——password参数被忽略。

还有其他问题。ECB 模式并不安全。这里的密钥推导非常弱。取决于平台默认字符编码不是一个好主意。

于 2013-08-26T08:59:16.940 回答