java填充错误中的AES解密

时间:2017-02-07 12:57:52

标签: java cryptography aes

我有一个使用Java解密AES的任务,但我不断收到pad block corrupted错误。我知道这个问题已经在多个线程中得到了解决,但我仍然无法弄明白。

我已将此信息提供给我:

键:0123456789abcdef

IV:0000000000000000

加密字符串:1ff4ec7cef0e00d81b2d55a4bfdad4ba

根据作业应该给出字符串“纯文本”。

这是我的代码:( IVtest数组与KeyIvEncrypted相同,但使用十六进制代替)

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

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

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.crypto.BufferedBlockCipher;

import java.util.Base64;



public class AESdecryptor {
/*
    private static String[] KeyIvEncrypted = new String[]{
            "ABEiM0RVZneImaq7zN3u/w==",
            "AAECAwQFBgcICQoLDA0ODw==",
            "ZtrkahwcMzTu7e/WuJ3AZmF09DE="
            };*/
    public static String[] KeyIvEncrypted = new String[]{
            new String("0123456789abcdef"),
            new String("0000000000000000"),
            new String("1ff4ec7cef0e00d81b2d55a4bfdad4ba")
            };
    public static byte[][] Ivtest = {{0x0,0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf},{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0x1,0xf,0xf,0x4,0xe,0xc,0x7,0xc,0xe,0xf,0x0,0xe,0x0,0x0,0xd,0x8,0x1,0xb,0x2,0xd,0x5,0x5,0xa,0x4,0xb,0xf,0xd,0xa,0xd,0x4,0xb,0xa}};

    public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidAlgorithmParameterException, UnsupportedEncodingException, InvalidKeySpecException{
        Security.addProvider(new BouncyCastleProvider());
        System.out.println(new String(decrypt(),"ISO-8859-1"));



    }

    private static byte[] transform(int mode, byte[] keyBytes, byte[] ivBytes, byte[] messageBytes) throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidKeySpecException
    {
        final SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
        final IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        final Cipher cipher = Cipher.getInstance("AES/CBC/pkcs7Padding");
        cipher.init(mode, keySpec, ivSpec);
        return cipher.doFinal(messageBytes);
    }

    public static byte[] decrypt() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchProviderException, InvalidAlgorithmParameterException, UnsupportedEncodingException, InvalidKeySpecException{
         //return AESdecryptor.transform(Cipher.DECRYPT_MODE, Base64.getDecoder().decode(KeyIvEncrypted[0]), Base64.getDecoder().decode(KeyIvEncrypted[1]), Base64.getDecoder().decode(KeyIvEncrypted[2]));
         return AESdecryptor.transform(Cipher.DECRYPT_MODE, Ivtest[0], Ivtest[1], Ivtest[2]);

    }
}

1 个答案:

答案 0 :(得分:1)

好的,所以我需要一些时间重新思考,我需要一个谜题。你是幸运儿。

以下代码将解决您的问题,我将在下面发表评论......

package so;

import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;

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

import org.bouncycastle.util.encoders.Hex;

public class AESdecryptor {
    public static String[] KeyIvEncrypted = new String[]{
            new String("0123456789abcdef"),
            new String("0000000000000000"),
            new String("1ff4ec7cef0e00d81b2d55a4bfdad4ba")
            };

    public static void main(String[] args) throws GeneralSecurityException {
        // Security.addProvider(new BouncyCastleProvider());
        byte[] decrypted = decrypt();
        System.out.println(new String(decrypted, StandardCharsets.ISO_8859_1));
    }

    private static byte[] transform(int mode, byte[] keyBytes, byte[] ivBytes, byte[] messageBytes)
            throws GeneralSecurityException {
        final SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
        final IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
        final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(mode, keySpec, ivSpec);
        return cipher.doFinal(messageBytes);
    }

    public static byte[] decrypt() throws GeneralSecurityException {
         return AESdecryptor.transform(Cipher.DECRYPT_MODE, KeyIvEncrypted[0].getBytes(), KeyIvEncrypted[1].getBytes(), Hex.decode(KeyIvEncrypted[2]));
    }
}

发现了以下问题:

  • 密钥和IV在(ASCII)文本中指定。密钥和IV不应编码为文本,因为每个字节应该是同等可能的;
  • IV不应该是静态的,但与随机无法区分;
  • IV不是“零”IV,因为它包含设置为0x00的字节,而不是设置为字符'0'的字节,即0x30;
  • 在填充时不需要Bouncy Castle,PKCS#5 is identical to PKCS#7;
  • 密文以十六进制编码,因此您需要使用两个十六进制数字对它们进行解码以组成一个字节(我已经使用了Bouncy中的Hex类,就像您已经拥有的那样)。 / LI>

请注意,即使正确执行,加密也不等于安全