你能弄清楚为什么这个程序会触发IllegalStateException吗?

时间:2021-12-21 00:36:55

all files in ~/Cipher/nsdl/crypto can be found here java files compiled with gcj, see compile.sh

〜/ Cipher / nsdl / crypto中的所有文件都可以在这里找到用gcj编译的java文件,参见compile.sh

nmint@nqmk-mint ~/Cipher/nsdl/crypto $ echo test | ./cryptTest encrypt deadbeefdeadbeefdeadbeefdeadbeef deadbeef Blowfish CBC > test
null
Exception in thread "main" java.lang.IllegalStateException: cipher is not for encrypting or decrypting
   at javax.crypto.Cipher.update(libgcj.so.81)
   at javax.crypto.CipherOutputStream.write(libgcj.so.81)
   at nsdl.crypto.BlockCrypt.encrypt(cryptTest)
   at nsdl.crypto.cryptTest.main(cryptTest)

BlockCrypt.java:

package nsdl.crypto;

import java.io.*;
import java.security.spec.*;
import javax.crypto.*;
import javax.crypto.spec.*;

public class BlockCrypt {
Cipher ecipher;
Cipher dcipher;
byte[] keyBytes;
byte[] ivBytes;
SecretKey key;
AlgorithmParameterSpec iv;
byte[] buf = new byte[1024];

BlockCrypt(String keyStr, String ivStr, String algorithm, String mode) {
    try {
        ecipher = Cipher.getInstance(algorithm + "/" + mode + "/PKCS5Padding");
        dcipher = Cipher.getInstance(algorithm + "/" + mode + "/PKCS5Padding");

        keyBytes = hexStringToByteArray(keyStr);
        ivBytes = hexStringToByteArray(ivStr);

        key = new SecretKeySpec(keyBytes, algorithm);
        iv = new IvParameterSpec(ivBytes);

        ecipher.init(Cipher.ENCRYPT_MODE, key, iv);
        dcipher.init(Cipher.DECRYPT_MODE, key, iv);
    } catch (Exception e) {
        System.err.println(e.getMessage());
    }
}

public void encrypt(InputStream in, OutputStream out) {
    try {
        // out: where the plaintext goes to become encrypted
        out = new CipherOutputStream(out, ecipher);

        // in: where the plaintext comes from
        int numRead = 0;
        while ((numRead = in.read(buf)) >= 0) {
            out.write(buf, 0, numRead);
        }
        out.close();
    } catch (IOException e) {
        System.err.println(e.getMessage());
    }
}

public void decrypt(InputStream in, OutputStream out) {
    try {
        // in: where the plaintext come from, decrypted on-the-fly
        in = new CipherInputStream(in, dcipher);

        // out: where the plaintext goes
        int numRead = 0;
        while ((numRead = in.read(buf)) >= 0) {
            out.write(buf, 0, numRead);
        }
        out.flush();
        out.close();
    } catch (IOException e) {
        System.err.println(e.getMessage());
    }
}
public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
        + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}
}

cryptTest.java:

package nsdl.crypto;

import nsdl.crypto.BlockCrypt;

public class cryptTest {

public static void main (String args[]) {
    if (args.length != 5) {
        System.err.println("Usage: cryptTest (encrypt|decrypt) key iv algorithm mode");
        System.err.println("Takes input from STDIN. Output goes to STDOUT.");
    } else {
        String operation = args[0];
        String key = args[1];
        String iv = args[2];
        String algorithm = args[3];
        String mode = args[4];
        BlockCrypt blockCrypt = new BlockCrypt(key, iv, algorithm, mode);
        if (operation.equalsIgnoreCase("encrypt")) {
            blockCrypt.encrypt(System.in, System.out);
        } else if (operation.equalsIgnoreCase("decrypt")) {
            blockCrypt.decrypt(System.in, System.out);
        } else {
            System.err.println("Invalid operation. Use (encrypt|decrypt).");
        }
    }
}
}

2 个解决方案

#1


2  

The Cipher, ecipher, is not initialized, and it throws an IllegalStateException when you try to use it as if it were initialized in ENCRYPT_MODE.

Cipher,ecipher,未初始化,当您尝试使用它时,它会抛出IllegalStateException,就像它在ENCRYPT_MODE中初始化一样。

Note your catch block in the constructor of BlockCrypt. It is catching an exception with no message, and printing "null" to System.err. Rather than aborting execution—perhaps by throwing an exception from the constructor—you keep sailing.

请注意BlockCrypt构造函数中的catch块。它捕获没有消息的异常,并向System.err打印“null”。而不是中止执行 - 也许是通过从构造函数中抛出异常 - 你继续航行。

Replacing System.err.println(e.getMessage()) with e.printStackTrace() or at least System.err.println(e) should give you more detail. My guess is that ecipher.init() is throwing an exception because you're providing a 32-bit IV instead of 64 bits.

用e.printStackTrace()或至少System.err.println(e)替换System.err.println(e.getMessage())可以为您提供更多详细信息。我的猜测是ecipher.init()抛出异常,因为你提供的是32位IV而不是64位。

#2


0  

Perhaps looking at the source for javax.crypto.Cipher helps this make sense? I couldn't really figure it out, even finding the error message in the source. Good luck!

或许查看javax.crypto.Cipher的源代码有助于理解这一点吗?即使在源代码中找到错误消息,我也无法弄明白。祝好运!

#1


2  

The Cipher, ecipher, is not initialized, and it throws an IllegalStateException when you try to use it as if it were initialized in ENCRYPT_MODE.

Cipher,ecipher,未初始化,当您尝试使用它时,它会抛出IllegalStateException,就像它在ENCRYPT_MODE中初始化一样。

Note your catch block in the constructor of BlockCrypt. It is catching an exception with no message, and printing "null" to System.err. Rather than aborting execution—perhaps by throwing an exception from the constructor—you keep sailing.

请注意BlockCrypt构造函数中的catch块。它捕获没有消息的异常,并向System.err打印“null”。而不是中止执行 - 也许是通过从构造函数中抛出异常 - 你继续航行。

Replacing System.err.println(e.getMessage()) with e.printStackTrace() or at least System.err.println(e) should give you more detail. My guess is that ecipher.init() is throwing an exception because you're providing a 32-bit IV instead of 64 bits.

用e.printStackTrace()或至少System.err.println(e)替换System.err.println(e.getMessage())可以为您提供更多详细信息。我的猜测是ecipher.init()抛出异常,因为你提供的是32位IV而不是64位。

#2


0  

Perhaps looking at the source for javax.crypto.Cipher helps this make sense? I couldn't really figure it out, even finding the error message in the source. Good luck!

或许查看javax.crypto.Cipher的源代码有助于理解这一点吗?即使在源代码中找到错误消息,我也无法弄明白。祝好运!