Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.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中使用三重des(3des)进行解密,得到错误;javax.crypto.IllegalBlockSizeException:解密中的最后一个块未完成”;_Java_Android_Encryption_3des - Fatal编程技术网

在java中使用三重des(3des)进行解密,得到错误;javax.crypto.IllegalBlockSizeException:解密中的最后一个块未完成”;

在java中使用三重des(3des)进行解密,得到错误;javax.crypto.IllegalBlockSizeException:解密中的最后一个块未完成”;,java,android,encryption,3des,Java,Android,Encryption,3des,我像这样使用代码,但当我使用解密它时,它得到了这样的错误 javax.crypto.IllegalBlockSizeException: last block incomplete in decryption 07-17 11:27:27.580: WARN/System.err(22432): at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(BaseBloc

我像这样使用代码,但当我使用解密它时,它得到了这样的错误

javax.crypto.IllegalBlockSizeException: last block incomplete in decryption
07-17 11:27:27.580: WARN/System.err(22432): at com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(BaseBlockCipher.java:705)
07-17 11:27:27.580: WARN/System.err(22432): at javax.crypto.Cipher.doFinal(Cipher.java:1111)
但如果我更改
final Cipher decipher=Cipher.getInstance(“DESede/CBC/pkcs5pdadding”)
to
final Cipher decipher=Cipher.getInstance(“DESede/CFB/NoPadding”),该方法可以运行,但得到错误的结果(模式与服务器不同)。
所以我想知道原因

解密方法:

public static String decrypt(byte[] message) throws Exception {
    final MessageDigest md = MessageDigest.getInstance("SHA-1");
    final byte[] digestOfPassword = md.digest(token.getBytes("utf-8"));
    final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
    for (int j = 0, k = 16; j < 8;) {
        keyBytes[k++] = keyBytes[j++];
    }

    final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
    final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
    final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    // final Cipher decipher = Cipher.getInstance("DESede/CFB/NoPadding");
    decipher.init(Cipher.DECRYPT_MODE, key, iv);
    final byte[] plainText = decipher.doFinal(message);
    return new String(plainText, "UTF-8");
}
public static byte[] encrypt(String message) throws Exception {
        final MessageDigest md = MessageDigest.getInstance("SHA-1");
        final byte[] digestOfPassword = md.digest(token
                .getBytes("utf-8"));
        final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
        for (int j = 0, k = 16; j < 8; ) {
            keyBytes[k++] = keyBytes[j++];
        }

        final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
        final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
        final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key, iv, new SecureRandom(new byte[5]));
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);

        final byte[] plainTextBytes = message.getBytes("utf-8");
        final byte[] cipherText = cipher.doFinal(plainTextBytes);
        return cipherText;
    }
公共静态字符串解密(字节[]消息)引发异常{
final MessageDigest md=MessageDigest.getInstance(“SHA-1”);
最后一个字节[]digestOfPassword=md.digest(token.getBytes(“utf-8”);
最终字节[]keyBytes=Arrays.copyOf(digestOfPassword,24);
对于(int j=0,k=16;j<8;){
keyBytes[k++]=keyBytes[j++];
}
最终SecretKey密钥=新SecretKeySpec(密钥字节,“DESede”);
最终IvParameterSpec iv=新的IvParameterSpec(新字节[8]);
final Cipher decipher=Cipher.getInstance(“DESede/CBC/PKCS5Padding”);
//final Cipher decipher=Cipher.getInstance(“DESede/CFB/NoPadding”);
decipher.init(Cipher.DECRYPT_模式,密钥,iv);
最终字节[]明文=decipher.doFinal(消息);
返回新字符串(纯文本,“UTF-8”);
}
加密方法:

public static String decrypt(byte[] message) throws Exception {
    final MessageDigest md = MessageDigest.getInstance("SHA-1");
    final byte[] digestOfPassword = md.digest(token.getBytes("utf-8"));
    final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
    for (int j = 0, k = 16; j < 8;) {
        keyBytes[k++] = keyBytes[j++];
    }

    final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
    final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
    final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
    // final Cipher decipher = Cipher.getInstance("DESede/CFB/NoPadding");
    decipher.init(Cipher.DECRYPT_MODE, key, iv);
    final byte[] plainText = decipher.doFinal(message);
    return new String(plainText, "UTF-8");
}
public static byte[] encrypt(String message) throws Exception {
        final MessageDigest md = MessageDigest.getInstance("SHA-1");
        final byte[] digestOfPassword = md.digest(token
                .getBytes("utf-8"));
        final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
        for (int j = 0, k = 16; j < 8; ) {
            keyBytes[k++] = keyBytes[j++];
        }

        final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
        final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
        final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key, iv, new SecureRandom(new byte[5]));
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);

        final byte[] plainTextBytes = message.getBytes("utf-8");
        final byte[] cipherText = cipher.doFinal(plainTextBytes);
        return cipherText;
    }
公共静态字节[]加密(字符串消息)引发异常{
final MessageDigest md=MessageDigest.getInstance(“SHA-1”);
最后一个字节[]digestOfPassword=md.digest(标记
.getBytes(“utf-8”);
最终字节[]keyBytes=Arrays.copyOf(digestOfPassword,24);
对于(int j=0,k=16;j<8;){
keyBytes[k++]=keyBytes[j++];
}
最终SecretKey密钥=新SecretKeySpec(密钥字节,“DESede”);
最终IvParameterSpec iv=新的IvParameterSpec(新字节[8]);
final Cipher=Cipher.getInstance(“DESede/CBC/PKCS5Padding”);
cipher.init(cipher.ENCRYPT_MODE,key,iv,新SecureRandom(新字节[5]);
cipher.init(cipher.ENCRYPT_模式,密钥,iv);
最终字节[]明文字节=message.getBytes(“utf-8”);
最终字节[]密文=cipher.doFinal(明文字节);
返回密文;
}

有许多可能性
最常见的是,如果您将密钥编码为字符串,尤其是在不指定字符编码的情况下。如果您想这样做,请使用Base-64,它设计用于对任何
二进制数据进行编码,而不是字符编码
还应确保源平台和目标平台编码应相同。当您在另一个en上使用
UTF-8
时,
UTF-8
必须使用

现在看看您所说的代码运行时使用的是
final Cipher decipher=Cipher.getInstance(“DESede/CFB/NoPadding”)
但不能使用
final Cipher decipher=Cipher.getInstance(“DESede/CBC/pkcs5pdadding”)
解密的时候,,您必须知道在加密时选择的填充大小和模式。正如您所说,当您使用
CBC
模式时,它会抛出异常,但当您将其更改为
CFB
时,它就可以运行了。在这种情况下,您需要确保在encrytpion使用的是哪种模式时间。

作为旁注:CBC、OFB和CFB是相同的,但是OFB/CFB更好,因为您只需要加密而不需要解密,这样可以节省代码空间。
CBC(密码块链接)用于数据通过AES函数的情况,并应用反馈修改预加密数据,以便重复的普通数据不会产生相同的加密数据。数据只能在与基础加密功能的块大小相匹配的块中处理(因此AES情况下为128位块),并且必须在加密和解密引擎之间提供此块级别的同步,否则数据将无法识别
CFB(密码反馈模式)也是一种常见模式,它提供了使底层分组密码像流密码一样工作的可能性;因此,正在处理的数据可以是较短值(例如字节或甚至单个位)的流,而不是仅处理较大的块。在CFB模式下,数据本身不经过AES引擎,而是与AES引擎根据以前的消息历史生成的值异或。这意味着通过CFB函数的延迟可以最小化,因为应用于数据的唯一处理是XOR函数。数据宽度可以设置为任何大小,直到基本密码块大小,但请注意,随着宽度在数据宽度与块大小的比率中变小,吞吐量会降低。(旁注结束:D)
如果使用密码反馈(CFB)或输出反馈(OFB)或计数器(CTR)模式进行加密,则密文的大小将与明文相同,因此不需要填充。但是,在使用这些模式时要小心,因为初始化向量(IV)必须是唯一的。
类似地,使用诸如RC4或PC1之类的流密码进行加密不需要填充。

现在,如果我们的调查比您更为严格,您应该注意块大小和填充大小(上面已经提到)。现在,您需要确保的第一件事是加密算法定义的填充大小。正如我提到的,在CFB情况下,不需要填充,所以请先尝试,而不提供填充。
如果问题仍然存在,则检查它是否为
pkcs5
pkcs7
。通过将decrytpion padding size设置为来尝试代码
pkcs7
。如果它是
pkcs7
,那么我想它也应该与CBC一起使用。我建议您阅读

作为附加信息

  • RFC 2898中定义了PKCS#5填充(PKCS#5: