2017-02-07 5 views
0

У меня есть назначение расшифровать AES с помощью Java, но я продолжаю получать поврежденную ошибку блока блока. Я знаю, что эта проблема была решена во многих потоках во всем мире, но я до сих пор не могу понять это.AES decryption in java padding error

У меня есть эта информация дана мне:

ключ:abcdef

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("abcdef"), 
      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]); 

    } 
} 
+0

Ваши входные строки являются шестнадцатеричными, но вы никогда не расшифровываете их на 'byte []'. – Robert

+1

@Robert, KeyIvEncrypted никогда не используется там. Автор, поэтому Маартен Бодьюс попросил вас очистить свой код. –

ответ

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("abcdef"), 
      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 когда дело доходит до прокладки;
  • Зашифрованный текст закодирован в шестнадцатеричном формате, поэтому вам нужно декодировать их, используя две шестнадцатеричные цифры, сгруппированные вместе, чтобы сделать один байт (я использовал класс Hex от Bouncy, поскольку у вас уже есть, что кажется).

И обратите внимание, что шифрование не равно безопасности , даже если выполнено правильно.

+0

Да, это работает, спасибо вам большое! Я на самом деле пытался решить эту проблему точно так же, как ваше решение, но я не знал, что вам нужно расшифровать их, используя класс Hex. Удивительный! – David

+0

Не забудьте нажать знак accept-V слева от ответа, если этот (или любой другой ответ) наилучшим образом отвечает на ваш вопрос. Это лучший способ выразить благодарность SO (и, конечно же, выжить, когда это доступно вам). –

+0

О, верно, опять. – David