Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.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加密/解密错误。有时会发生解密错误_Java_Encryption_Cryptography - Fatal编程技术网

Java加密/解密错误。有时会发生解密错误

Java加密/解密错误。有时会发生解密错误,java,encryption,cryptography,Java,Encryption,Cryptography,我有以下简单的加密/解密代码: import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.RandomStringUtils; : public cl

我有以下简单的加密/解密代码:

import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.RandomStringUtils;
          :

public class MyUtility {

    private static Cipher instance = Cipher.getInstance("AES/CBC/PKCS5Padding");
    private static Cipher instance2 = Cipher.getInstance("AES/CBC/PKCS5Padding");
    private static byte[] iv = { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };

    private static String encrypt(String data, DataParameters params) throws Exception {

        IvParameterSpec ivspec = new IvParameterSpec(iv);
        String privateKey = MyUtility.getKey(params);

        SecretKey key = new SecretKeySpec(privateKey.getBytes(), "AES");
        instance.init(Cipher.ENCRYPT_MODE, key, ivspec);

        String paddedData = addPaddDate(data); 
        byte[] encryptedBytes = instance.doFinal(paddedData.getBytes());
        byte[] encodeBase64 = Base64.encodeBase64(encryptedBytes); 
        String encryptedStr = new String(encodeBase64);
然后很快执行解密:

    byte[] decodeBytes = Base64.decodeBase64(encryptedStr.getBytes()); // Decode
    String padDecryptedStr = new String(instance2.doFinal(decodeBytes)); 
然后95%的时间,解密的值是正确的。但是,我偶尔会遇到以下错误:

javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:420)
    at javax.crypto.Cipher.doFinal(Cipher.java:1966)
    at myCode.decrypt(MyEncryptDecryptUtility.java:97)
其中第97行是
String padDecryptedStr=新字符串(instance2.doFinal(decodeBytes))

解密后的值看起来像是奇怪的字符串,比如:\u001d��tq@s�2.�或�W�����$�X\u0005

这是我使用的填充函数:

private static String addPaddDate(String data) {
    return data + RandomStringUtils.randomAlphanumeric(10);
}
你知道上面的代码缺少什么吗

谢谢大家!


只是想更新我发现的更多信息:


当解密的值是一个奇怪的字符串时,我再次解密,然后第二次得到正确的值。有人知道为什么吗?谢谢

作业有多个cpu核,因此多个任务访问同一个密码并损坏了编码。我同步了encrypt()和decrypt()函数,现在一切正常。

您是否编写了自己的base 64以及填充方法?还是使用GET请求发送数据?只是添加了我上面使用的填充方法。谢谢你能创建一个MCVE吗?你甚至没有提供加密代码。请注意,我询问的是base 64代码或库,而不是padding方法。首先,为什么要执行自己的填充?请注意,使用错误的密钥(对于非常小的密文,甚至是IV)也会创建一个
BadPaddingException
String.getBytes()
新字符串(byte[])
可能使用不同的字符集,从而损坏数据。选择一个合适的字符集,并在两端指定它;UTF-8在任何情况下都是流行且安全的。
instance.init(Cipher.ENCRYPT_MODE,key);字节[]iv=实例.getIV()
我不确定创建(潜在的阻塞操作)和管理
SecureRandom
实例如何比这更简单。当您每次指定相同的IV时,攻击者可以判断您正在加密相同的消息。IV的目的是从同一消息生成不同的密码文本。如果纯文本长度超过一个块,则填充将不起作用。它只会更改消息的结尾。正确使用IV将更改整个密码文本。