我有一个密文和一个256位密钥,使用AES解密它。没有盐或静脉注射。我正在使用Java。我已经在线实现了许多解决方案,但它们都使用盐和输入向量。以下构建正常,但在运行时失败:"找不到Salt。"什么盐?
public class AESFileDecryption {
public static void main(String[] args) throws Exception {
String password = "80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01";
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec keySpec = new PBEKeySpec(password.toCharArray());
SecretKey tmp = factory.generateSecret(keySpec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
// file decryption
Cipher cipher = Cipher.getInstance();
cipher.init(Cipher.DECRYPT_MODE,secret);
FileInputStream fis = new FileInputStream("encryptedfile.des");
FileOutputStream fos = new FileOutputStream("plainfile_decrypted.txt");
byte[] in = new byte[64];
int read;
while ((read = fis.read(in)) != -1) {
byte[] output = cipher.update(in, 0, read);
if (output != null)
fos.write(output);
}
byte[] output = cipher.doFinal();
if (output != null)
fos.write(output);
fis.close();
fos.flush();
fos.close();
System.out.println("File Decrypted");
}
}
答案 0 :(得分:1)
您可以使用AES的简单ECB模式解密练习3.8中的密文,该模式不使用IV。由于你有钥匙,所以不需要盐(没有钥匙派生)。在Java中使用AES 256 ECB模式,并如图所示传递密钥。命令行中的这些openssl命令显示这将起作用:
您必须将书中显示的十六进制转换为字符串,例如:
echo '539B333B39706D149028CFE1D9D4A407' | xxd -r -p
您必须将密钥用作32个字节的字符串,例如,openssl命令行使用-K参数将十六进制转换为字节:
-K 80000000000000000000000000000000000000000000000000000000000001
您可以将生成的二进制明文转换回十六进制字符串以供查看,如
xxd -p
例如:
echo '539B333B39706D149028CFE1D9D4A407' | xxd -r -p | openssl enc -aes-256-ecb -nopad -d -K 8000000000000000000000000000000000000000000000000000000000000001 | xxd -p
结果是:
80706050403020100807060504030201
如果让Java类剥离填充,结果将是15字节的明文:
807060504030201008070605040302
这应该足以让您使用Java类并重现相同的结果。我只想告诉你,这将适用于AES 256 ECB,不涉及任何IV或盐。
答案 1 :(得分:0)
IV通常与加密模式(如CBC)一起使用。我假设Schneier在这里使用ECB,这并不涉及IV。 ECB模式通常不在现实世界中使用,因为它缺乏安全性。我建议你看一下WIkipedia modes of operation文章。盐更多了。
如果您同意这是您正在处理的问题,那么您可能希望查看here以便在ECB模式下加密Java代码。
答案 2 :(得分:0)
这里的答案都是关于使用ECB的正确答案,因此不需要IV(或填充)。这是问题3.8的更新Java答案:
String hexCipherText = "539b333b39706d149028cfe1d9d4a407";
String hexSecretKey = "80000000000000000000000000000000" +
"00000000000000000000000000000001";
byte[] secretKey = DatatypeConverter.parseHexBinary (hexSecretKey);
byte[] cipherText = DatatypeConverter.parseHexBinary (hexCipherText);
Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey,"AES");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] plainText = cipher.doFinal(cipherText);
String hexPlainText = DatatypeConverter.printHexBinary(plainText);
如果您收到错误java.security.InvalidKeyException: Illegal key size or default parameters
并且您正在使用Oracle JDK,那么您可能还需要下载Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files。