2015-12-20 3 views
0

Я получаю следующее сообщение об ошибке при попытке расшифровано:Как правильно расшифровать javax.crypto зашифрована строка

javax.crypto.IllegalBlockSizeException: Длина входной должна быть кратна 16 при расшифровке с мягким шифром

Вот класс шифрования я реализовал:

import java.io.UnsupportedEncodingException; 
import java.security.InvalidKeyException; 
import java.security.Key; 
import java.security.NoSuchAlgorithmException; 

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

public class StringEncrypter { 

    public static String encrypt(String key, String string, String algorithm) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException { 
     Key aesKey = new SecretKeySpec(key.getBytes("UTF-8"), algorithm); 
     Cipher cipher = Cipher.getInstance(algorithm); 
     cipher.init(Cipher.ENCRYPT_MODE, aesKey); 
     byte[] encrypted = cipher.doFinal(string.getBytes()); 
     return encrypted.toString(); 
    } 

    public static String decrypt(String key, String encryptedString, String algorithm) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException { 
     Key aesKey = new SecretKeySpec(key.getBytes("UTF-8"), algorithm); 
     Cipher cipher = Cipher.getInstance(algorithm); 
     cipher.init(Cipher.DECRYPT_MODE, aesKey); 
     String decrypted = new String(cipher.doFinal(encryptedString.getBytes())); 
     return decrypted; 
    } 
} 

Это, как я зашифрован строка:

StringEncrypter.encrypt("0306868080306868", "ddd", "AES"); // [[email protected] 

При попытке расшифровать зашифрованную строку выше следующим образом:

String decrypted = StringEncrypter.decrypt("0306868080306868", "[[email protected]", "AES"); 

Я получаю illegalBlockSizeException.

Что я делаю неправильно выше? Как правильно дешифровать зашифрованную строку?

+0

Обратите внимание, что вы, кажется, использует ECB шифрование, которое не является безопасным. Вы, по крайней мере, пропустили (случайно) IV в своем коде. –

+0

Возможный дубликат [Java: Синтаксис и значение позади "\ [B @ 1ef9157"? Двоичный/Адрес?] (Http://stackoverflow.com/questions/1040868/java-syntax-and-meaning-behind-b1ef9157-binary-address) –

+0

@ArtjomB. Он объясняет, как генерируется вывод, но заменяя его на 'new String (byte [])', например. не решить проблему. –

ответ

2

Для вашего ключа и вашего зашифрованного текста необходимо выполнить декодирование с базовым 64-кодированием. Для этого в Java 8 есть новый класс Base64. Вы не можете просто сохранить какой-либо байт в строке, не все байты представляют собой печатные или даже допустимые символы, а вывод шифрования неотличим от случайного.

Кроме того, массив байт «класс» (представлен [B в Java) не реализует toString метода, который означает, что вы просто получить распечатку Object.toString, т.е. имя класса [B и читаемые идентификаторы экземпляр объекта вместо фактического зашифрованного текста.

+0

Зачем мне нужно кодирование и декодирование базы 64? Также есть вариант 1.7 - я не могу использовать Java 8, к сожалению. – crm

+1

Bouncy castle и библиотека Apache Commons Codec для спорта Base64. Вам нужно выполнить кодировку base64 (и, действительно, декодирование), потому что не каждая двоичная строка может быть представлена ​​текстовой строкой без кодирования. Вы также можете просто сохранить шифрованный текст/ключ как массив байтов, конечно, если вам действительно не нужно текстовое представление строки. –

+0

«Как указано в« Дорожной карте поддержки Oracle JDK », после апреля 2015 года Oracle не будет размещать дополнительные обновления Java SE 7 на своих общедоступных сайтах загрузки.Клиенты, которым необходим постоянный доступ к критическим исправлениям ошибок и исправлениям безопасности, а также общее обслуживание для Java SE 7 или более ранних версий, могут получить долгосрочную поддержку через поддержку Oracle Java SE. «... поэтому вы создаете приложение, связанное с безопасностью в Java 7. Вы уверены, что знаете, что делаете? –

0

Вы не можете использовать байты (двоичные) в качестве строки. он не эквивалентен

Его следует преобразовать. Несколько манер. Base64 или гекса, например You с base64, он дает это:

import javax.xml.bind.DatatypeConverter ; 

byte[] bt= ... // what you get 

// Conversion B64 
String encodedb64=DatatypeConverter.printBase64Binary(bt); 

// CONVERSION base 64 => byte 
// base 64 => byte 
byte [] byteArrayreverse=DatatypeConverter.parseBase64Binary(encodedb64); 
Смежные вопросы