Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中没有salt或iv的代码解密失败_Java_Security_Encryption_Aes_Password Encryption - Fatal编程技术网

Java中没有salt或iv的代码解密失败

Java中没有salt或iv的代码解密失败,java,security,encryption,aes,password-encryption,Java,Security,Encryption,Aes,Password Encryption,我有一个密文和一个256位密钥来解密它,使用AES。没有盐或iv。我使用Java。我已经在线实现了许多解决方案,但它们都使用了盐和输入向量。以下构建很好,但在运行时失败:“找不到盐”。什么盐 public class AESFileDecryption { public static void main(String[] args) throws Exception { String password = "80 00 00 00 00 00 00 00 00

我有一个密文和一个256位密钥来解密它,使用AES。没有盐或iv。我使用Java。我已经在线实现了许多解决方案,但它们都使用了盐和输入向量。以下构建很好,但在运行时失败:“找不到盐”。什么盐

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

}IVs通常与加密模式(如CBC)一起使用。我假设Schneier在这里使用ECB,它不涉及IV。ECB模式在现实世界中通常不使用,因为它缺乏安全性。我建议你看看维基百科的文章。盐的含量更高


如果您同意这是您正在处理的问题,那么您可能需要寻找java代码以在ECB模式下进行加密。

您可以使用AES的简单ECB模式解密练习3.8中的密文,该模式不使用IV。因为您有密钥,所以不需要salt(没有密钥派生)。在Java中使用AES 256 ECB模式,并如图所示传递密钥。命令行中的这些openssl命令表明这将起作用:

您必须将书中显示的十六进制转换为一个字节字符串,例如:

echo '539B333B39706D149028CFE1D9D4A407' | xxd -r -p
echo '539B333B39706D149028CFE1D9D4A407' | xxd -r -p | openssl enc -aes-256-ecb -nopad  -d -K 8000000000000000000000000000000000000000000000000000000000000001 | xxd -p
您必须将密钥用作32字节的字符串,例如,openssl命令行使用-K参数将十六进制转换为字节:

-K 80000000000000000000000000000000000000000000000000000000000001
您可以将生成的二进制明文转换回十六进制字符串以供查看,如中所示

xxd -p
例如:

echo '539B333B39706D149028CFE1D9D4A407' | xxd -r -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,不涉及任何静脉注射或盐。

关于使用ECB,这里的两个答案都是正确的,因此不需要静脉注射(或填充)。下面是问题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:非法密钥大小或默认参数
,并且您正在使用Oracle JDK,则您可能还需要下载。

StackOverflow用于解决与编程相关的特定问题。你有一个规范,我想是家庭作业或作业。您需要阅读规范,进行一些研究和/或学习,并开始编写解决方案。StackOverflow不会为您编写代码。如果您在编写解决方案时遇到问题,请发布其他问题。如果您将其表述为“在没有salt或IV的情况下解密如何工作?”而不是“我需要能够…”,那么这可能是一个更好的问题。PBKDF2WithHmacSHA1需要salt。我想Schneier是直接给你钥匙的,所以这意味着你不应该在HMACSHA1中使用PBKDF2。更多详细信息,请参见下面我回答中的评论。非常感谢。当我编辑我的问题以回应之前的批评时,你的回答非常有用。(对于那些想知道为什么答案似乎有点离题的人来说,这是我的错)。谢谢,我会继续。事实上,我从施奈尔的书中得到了很多东西。我只需要真正彻底地理解安全性,所以我作为一个相对的新手正在钻研代码领域,并且在这个练习中遇到了麻烦。不用担心。事实上,虽然我没有看过施奈尔的书,但我对加密技术非常了解,我很确定你的问题是“PBKDF2WithHmacSHA1”。PBKDF2用于将密码转换为密钥,而我猜Schneier会直接为您提供密钥(而不是密码)。有关如何正确设置键,请参阅我引用的链接(“此处”)。链接中的另一件事是使用ECB模式,而不是CBC模式,这是您应该做的。