javax.crypto.IllegalBlockSizeException:使用填充密码进行解密时,输入长度必须是16的倍数 [英] javax.crypto.IllegalBlockSizeException : Input length must be multiple of 16 when decrypting with padded cipher

查看:1098
本文介绍了javax.crypto.IllegalBlockSizeException:使用填充密码进行解密时,输入长度必须是16的倍数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在java类中遇到解密错误:

I'm getting a decrypting error in java class:

javax.crypto.IllegalBlockSizeException : 
    Input length must be multiple of 16 when decrypting with padded cipher.

我可以如何解决这个问题?

What can I do to solve this problem?

更新:

我忘了提及它正在工作,当第二次尝试再次执行它时,抛出上述错误。

I forgot to mention it is working once and when the second time im trying to execute it again its throwing the above mentioned error.

package com.tb.module.service;
import java.security.Key;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.*;

/**
 * This class is used for encrypt and decrypt the  password field.
 *
 */
public class PswdEnc {

    private static final String ALGO = "AES";
    private static final byte[] keyValue = new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't','S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };

    public static String encrypt(String Data) throws Exception {
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.ENCRYPT_MODE, key);
        byte[] encVal = c.doFinal(Data.getBytes());
        String encryptedValue = new BASE64Encoder().encode(encVal);
        return encryptedValue;
    }

    public static String decrypt(String encryptedData) throws Exception {
        Key key = generateKey(); 
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
        byte[] decValue = c.doFinal(decordedValue);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    }


    private static Key generateKey() throws Exception {
        Key key = new SecretKeySpec(keyValue, ALGO);
        return key;
    }

}


推荐答案

您使用的算法AES是AES / ECB / NoPadding的缩写。这意味着您正在使用128位密钥大小的 AES算法,而块大小 ECB 操作模式无填充

The algorithm you are using, "AES", is a shorthand for "AES/ECB/NoPadding". What this means is that you are using the AES algorithm with 128-bit key size and block size, with the ECB mode of operation and no padding.

换句话说:您只能以128位或16字节的块加密数据。这就是为什么你得到那个 IllegalBlockSizeException 异常。

In other words: you are only able to encrypt data in blocks of 128 bits or 16 bytes. That's why you are getting that IllegalBlockSizeException exception.

如果你想加密数据的大小不是16字节,你将要使用某种填充或密码流。例如,您可以使用 CBC模式(有效地转换块的操作模式通过指定AES / CBC / NoPadding作为算法,将密码加密成流密码),或通过指定AES / ECB / PKCS5,它将以非常特定的格式自动在数据结尾添加一些字节,使密文的大小为16字节的倍数,并且解密算法将以这种方式理解它必须忽略一些数据。

If you want to encrypt data in sizes that are not multiple of 16 bytes, you are either going to have to use some kind of padding, or a cipher-stream. For instance, you could use CBC mode (a mode of operation that effectively transforms a block cipher into a stream cipher) by specifying "AES/CBC/NoPadding" as the algorithm, or PKCS5 padding by specifying "AES/ECB/PKCS5", which will automatically add some bytes at the end of your data in a very specific format to make the size of the ciphertext multiple of 16 bytes, and in a way that the decryption algorithm will understand that it has to ignore some data.

无论如何,我强烈建议您现在停止所做的工作,并学习一些关于密码学的介绍性材料。例如,检查加密我在Coursera上。你应该很好地理解选择一种模式或另一种模式的含义,它们的优点是什么,最重要的是它们的弱点。没有这种知识,很容易构建很容易破坏的系统。

In any case, I strongly suggest that you stop right now what you are doing and go study some very introductory material on cryptography. For instance, check Crypto I on Coursera. You should understand very well the implications of choosing one mode or another, what are their strengths and, most importantly, their weaknesses. Without this knowledge, it is very easy to build systems which are very easy to break.

更新:根据您的意见在这个问题上,在将数据存储在数据库时不要加密密码 !!!!!你永远不应该这样做。您必须 HASH 密码,正确加密,这与加密完全不同。真的,请不要做你想做的事情...通过加密密码,他们可以解密。这意味着,作为数据库管理员,谁知道密钥,您将能够读取存储在数据库中的每个密码。或者你知道这一点,做的非常非常糟糕,或者你不知道这一点,应该感到震惊并阻止它。

Update: based on your comments on the question, don't ever encrypt passwords when storing them at a database!!!!! You should never, ever do this. You must HASH the passwords, properly salted, which is completely different from encrypting. Really, please, don't do what you are trying to do... By encrypting the passwords, they can be decrypted. What this means is that you, as the database manager and who knows the secret key, you will be able to read every password stored in your database. Either you knew this and are doing something very, very bad, or you didn't know this, and should get shocked and stop it.

这篇关于javax.crypto.IllegalBlockSizeException:使用填充密码进行解密时,输入长度必须是16的倍数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆