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

AES-128加密字符串未正确填充

凌炜
2023-03-14
package com.company.encrypt.tests;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

public class TestEncryptDecrypt {

    private static final String characterEncoding = "UTF-8";
    private static final String cipherTransformation = "AES/CBC/PKCS5Padding";
    private static final String aesEncryptionAlgorithm = "AES";

    public static void main(String[] args) throws Exception {
        String key1 = "1234567812345678";
        String text = "01234567891234565";
        System.out.println("Original Text: " + text);
        String encrypted = encrypt(text, key1);
        System.out.println("Encrypted: " + encrypted);
        String decrypted = decrypt(encrypted, key1);
        System.out.println("Decrypted: " + decrypted);

    }

    public static String decrypt(String encryptedText, String key) throws Exception {
        String plainText = null;

        int keyLength = key.length();
        System.out.println("Key length: " + String.valueOf(keyLength));
        byte[] encryptedTextBytes = Base64.decodeBase64(encryptedText.getBytes());
        byte[] keyBytes = key.getBytes();

        byte[] initialVector = Arrays.copyOfRange(encryptedTextBytes, 0, keyLength);
        byte[] trimmedCipherText = Arrays.copyOfRange(encryptedTextBytes, keyLength, encryptedTextBytes.length);

        try {
            Cipher cipher = Cipher.getInstance(cipherTransformation);
            SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, aesEncryptionAlgorithm);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

            byte[] clearText;
            clearText = cipher.doFinal(trimmedCipherText);

            plainText = new String(clearText, characterEncoding);
        } catch(NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException
                | InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return plainText;

    }

    public static String encrypt(String plainText, String encryptionKey) throws Exception {

        SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), aesEncryptionAlgorithm);
        Cipher cipher = Cipher.getInstance(cipherTransformation);
        cipher.init(Cipher.ENCRYPT_MODE, key);

        byte[] plainTextBytes = plainText.getBytes("UTF-8");

        byte[] encrypted = cipher.doFinal(plainTextBytes);

        return new String(Base64.encodeBase64(encrypted));
    }

}

共有1个答案

昝光临
2023-03-14

我注意到,在decrypt()函数中,您将加密数组分成两部分:前16个字节,其余部分。您使用前16个字节作为IV进行解密,但是,您没有在encrypt()中将16个字节IV前置到加密消息的开头。这将导致明文的前16个字节丢失。我想您认为dofinal()会自动为您做这件事,但事实并非如此。

要解决此问题,在返回加密消息之前,请预置IV,可以使用cipher.getiv()检索该IV。您可以使用Apache Commons Lang库中的arrayutils.addAll()来完成这一操作,也可以简单地编写自己的函数来完成这一操作。另一个需要注意的是,IV始终是块大小,对于AES来说是16字节,无论密钥大小如何。

希望这个答案有所帮助!

 类似资料:
  • 我使用初始化向量和填充实现了AES 128位加密,如下面的代码所示。我碰巧使用了ColdFusion,但我认为这并不重要。加密结果显示了一些重复模式,这是我没有预料到的,但话说回来,我不知道正确输出的特征。我是否正确地进行了初始化向量和填充? 下面是示例输出: 每个加密字符串都以相同的21个字符结尾: 当原始字符串相同(第3和第4个示例中的“String3”)时,EncryptedString以相

  • 我正在尝试编写方法来加密或解密字符串(大部分是数字)。它适用于某些文本(例如-'1010000011'、'1010000012'、'1010000013'),但也适用于其他文本(例如-'1010000014'、'1010000018'): javax.crypto.BadPadding异常:给定最后一个块没有正确填充 这是我的代码: 要加密的字符串从文件中读取,并在加密后写入其他文件。这些加密的文

  • 尝试将数据解密为用AES-128加密的字节数组,使用字符串密钥"keykeykeykey1" 代码: 给我BadPaddingExc0019。我错过了什么?

  • 所以我有一个AES-256-ecb base64字符串,我用在线工具解码了它。然而,我更喜欢命令行,所以我尝试使用命令行来解码它。 这是我尝试过的,但我得到了严重的解密错误 是加密的base64文本 -aes-256-ecb是加密密码 而366a74cb3c959de17d61db30591c39d1是关键 结果应该是另一个base64字符串:

  • 我得到的输出是: 有人能解释一下是怎么回事吗?我在互联网上看到了很多这样的例子,它们看起来都很好。但在这里,文本没有被解密。 ps:我使用的版本是