线程java.lang.IllegalStateException中的异常:密码未初始化

线程java.lang.IllegalStateException中的异常:密码未初始化,java,multithreading,encryption,cryptography,illegalstateexception,Java,Multithreading,Encryption,Cryptography,Illegalstateexception,在运行时,在解密密文时获取java.lang.IllegalStateException with Cipher not initialized消息 我的代码如下: public String decrypt(String cipherText) throws SecurityException { String clearText = null; try { cipher = Cipher.getInstance("AES/OFB/NoP

在运行时,在解密密文时获取java.lang.IllegalStateException with Cipher not initialized消息 我的代码如下:

public String decrypt(String cipherText) throws SecurityException {
        String clearText = null;
        try {
            cipher = Cipher.getInstance("AES/OFB/NoPadding");
            byte[] cipherTextBytes = Base64.decodeBase64(cipherText.getBytes());
            byte[] iv = ArrayUtils.subarray(cipherTextBytes, 0, INIT_VECTOR_LENGTH);
            cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
            byte[] decryptedBytes = cipher
                    .doFinal(ArrayUtils.subarray(cipherTextBytes, INIT_VECTOR_LENGTH, cipherTextBytes.length));
            clearText = new String(decryptedBytes, CHARACTER_ENCODING).trim();
        } catch (InvalidKeyException | IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException
                | NoSuchAlgorithmException | NoSuchPaddingException | InvalidAlgorithmParameterException e) {
            throw new SecurityException(e);
        }
        return clearText;
    }
线程池-5-thread-3 java.lang.IllegalStateException中出现异常:密码未初始化 在javax.crypto.Cipher.checkCipherStateChipher.java:1749 在javax.crypto.Cipher.doFinalCipher.java:2156

这是一个间歇性的问题,经过一段时间后,它会解密密文并按预期工作。

密码实例是有状态的,本质上不是线程安全的。您根本不应该在线程之间共享它们。也没有必要,因为它们是相对较轻的物体;使它们线程安全可能会降低应用程序的速度,而不仅仅是重新创建对象实例。如果需要重用密钥,最好将密钥放入一个字段并共享该字段。然后只需调用getInstanceAES/OFB/NoPadding并将密码实例分配给一个局部变量

旁注:代码似乎包含两个问题:第一个问题是cipher字段,但由于它在解密第二个问题中每次都被初始化。这意味着init调用实际上可能会替换CipherSpi或Security.Service的对象实例,即从另一个线程中实现密码,从而导致您现在遇到的错误

与多线程一样,在特定情况下很可能不会出现错误:但是程序是错误的,以后可能会崩溃。

密码实例是有状态的,本质上不安全。您根本不应该在线程之间共享它们。也没有必要,因为它们是相对较轻的物体;使它们线程安全可能会降低应用程序的速度,而不仅仅是重新创建对象实例。如果需要重用密钥,最好将密钥放入一个字段并共享该字段。然后只需调用getInstanceAES/OFB/NoPadding并将密码实例分配给一个局部变量

旁注:代码似乎包含两个问题:第一个问题是cipher字段,但由于它在解密第二个问题中每次都被初始化。这意味着init调用实际上可能会替换CipherSpi或Security.Service的对象实例,即从另一个线程中实现密码,从而导致您现在遇到的错误

与多线程一样,在特定情况下,很可能不会出现错误:然而,程序是错误的,以后可能会崩溃