当前位置: 首页 > 知识库问答 >
问题:

AES解密不工作超过16字节

丰岳
2023-03-14

我在Java中使用AES加密/解密时遇到了一个非常奇怪的问题。如果我加密/解密的字符串小于16字节,则密码可以正常工作,但如果我向密码提供大于16字节的任何内容,则会出现错误“给定最终块未正确填充”。我构建了一些小代码作为示例:

package com.company;

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

public class Main {

    public static void main(String[] args) {
        try {
            Cipher aesEncrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
            Cipher aesDecrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");

            SecretKeySpec key = new SecretKeySpec("ABCDEQWERTASDFGA".getBytes(), "AES");

            IvParameterSpec ivSpec = new IvParameterSpec(new byte[16]);

            aesDecrypt.init(Cipher.DECRYPT_MODE, key, ivSpec);
            aesEncrypt.init(Cipher.ENCRYPT_MODE, key, ivSpec);

            byte[] message = "Hello".getBytes();

            aesEncrypt.update(message);

            byte[] encrypted = aesEncrypt.doFinal();

            aesDecrypt.update(encrypted);

            byte[] decrypted = aesDecrypt.doFinal();

            System.out.println(new String(decrypted, "UTF-8"));
        }
        catch (Exception e){
            e.printStackTrace();
        }
    }
}

当byte[]消息为“Hello”时,加密/解密工作正常,但当我将其更改为“hellomybabyhellomydright”时,它抛出异常。有人知道我做错了什么吗?

共有1个答案

惠志
2023-03-14

Cipher#update(byte[])返回一个由于某种原因您没有使用的byte[]。您只是扔掉了除了最后一个块之外的所有内容(Cipher#doFinal()在应用填充后返回最后一个加密块)。如果您的消息仅由单个块组成,那么密文和解密的明文将是完整的。

由于您使用的是短消息,因此根本不需要使用密码更新。只需使用密码doFinal(字节[]):

byte[] message = "Hello".getBytes();
byte[] encrypted = aesEncrypt.doFinal(message);
byte[] decrypted = aesDecrypt.doFinal(encrypted);

如果您试图加密较长的数据(可能无法放入内存),则应将密码更新结果写入输出流,或使用不带更新或doFinal调用的CipherOutputStream。

 类似资料:
  • 我再次问这个问题,因为我的最后一个问题没有得到正确的回答,我正在制作一个CMS,我已经制作了一个加密系统(使用cryptoJs),为不使用ssl或tls的网站所有者提供多一点安全性。但当我用php解密代码时,我得到了以下信息: ÿÿÿÿ/Œæ 我试着看看它是不是十六进制,但当我试着把它从十六进制转换到UTF-8时,它也只给了我吉卜里什。 我的系统是这样工作的:每次用户进入一个页面,就会创建两个随机

  • 我使用Botan库进行加密,我的加密代码如下所示。 这段代码看起来很好,可以加密输入文件。我发布这段代码是为了确定加密是否有错误。(但我假设加密做得正确)

  • 这应该是一个简单的问题,但我无法从openssl文档中找到任何示例或答案。 我想加密128位,应该适合一个加密块。 所以我调用,然后呢? 我是否调用(加密 128 位块)和(即使没有更多要加密的内容)? 还是只有?还是只有?

  • 我有一些使用AES / CBC / PKCS5在Java中填充的解密数据。我正在加密两个值A和B,然后从文件中提取数据。加密的值按所述顺序写入文件。当解密各个部分的字节正确定位(通过调试确认)并且解密函数的输入正确时,没有填充问题。 加密代码: 加密时,我可以看到Cipher内部的向量在每次更新()后都按预期更新(最后一个密文是后续更新的向量。例如,加密A是我调用更新(B)时密码的向量 解密码 现

  • 我做了一个简单的文件加密/解密器。它将模式和要操作的文件作为参数。加密时,它生成随机字符串并使用该字符串加密文件。解密文件时,它会提示用户输入密码,并在解密时使用该密码。 我的问题是,解密时得到的不是明文,而是胡言乱语,尽管我小心翼翼地将相同的密钥写入输入。 非常感谢James K Polk提供的加密/解密代码!

  • 我试图在Android和PHP端使用AES加密/解密数据,并累犯空答案。 首先,我在Android中生成了对称密钥: 在服务器端,我试图解密数据。我可以解密(从RSA)秘密的AES密钥,并得到它的字符串表示。在客户端(Android)和服务器端(PHP)上是一样的。但是如何使用这个字符串AES密钥来解密数据呢?我尝试了这个(PHP): PHP中的结果: 怎么啦?