2017-01-16 4 views
1

Я должен реализовать базовое шифрование в своей программе. Я могу использовать Base64, который был отклонен клиентом. Поэтому я использую следующие методы. Проблема, с которой я сталкиваюсь, заключается в том, что в зашифрованном виде есть специальные символы, которые приводят к исключениям. Могу ли я изменить этот код, чтобы каким-то образом зашифровать простой текст без специальных символов.Как шифровать текст только в текстовые строки

protected static byte[] encrypt(String text) 
    { 
     try 
     { 
      String key = "6589745268754125"; 
      // Create key and cipher 
      Key aesKey = new SecretKeySpec(key.getBytes(), "AES"); 
      Cipher cipher = Cipher.getInstance("AES"); 
      // encrypt the text 
      cipher.init(Cipher.ENCRYPT_MODE, aesKey); 
      byte[] encrypted = cipher.doFinal(text.getBytes()); 
      return encrypted; 
     } 
     catch(Exception ex) 
     { 
      WriteLog("Encryption Failed"); 
      WriteLog(ex.getMessage()); 
      return null; 
     } 
    } 

protected static String decrypt(byte[] pass) 
{ 
    try 
    { 
     String key = "6589745268754125"; 
     // Create key and cipher 
     Key aesKey = new SecretKeySpec(key.getBytes(), "AES"); 
     Cipher cipher = Cipher.getInstance("AES"); 
     // decrypt the text 
     cipher.init(Cipher.DECRYPT_MODE, aesKey);   
     String decrypted = new String(cipher.doFinal(pass));   
     return decrypted; 
    } 
    catch(Exception ex) 
    { 
     WriteLog("Encryption Failed");  
     WriteLog(ex.getMessage()); 
     return null; 
    } 
} 

Сообщение об исключении говорит: «Учитывая заключительный блок не правильно проложенный» javax.crypto.BadPaddingException: Учитывая заключительный блок не правильно проложенный

+1

В чем проблема? Какое исключение? Где исключение? – nicomp

+0

Base64 - это кодировка, а не шифрование. Если вы хотите получить текстовое представление зашифрованных байтов, base64 - хороший способ его кодирования. – shmosel

+0

Я знаю, я пытаюсь получить кодировку, но теперь мне нужно сделать шифрование – Moon

ответ

0

Проблема была дополнением. Я использовал AES/CBC/NoPadding и убедитесь, что мои строки кратно 16 байтам. Поэтому, помимо изменения шифрования и расшифровки, мне пришлось добавить два метода. Один для добавления \0 i.e подразумеваемых нулевых терминаторов в конец текста, чтобы сделать его кратным 16, а другой - удалить их после дешифрования. Итак, окончательная версия выглядит так.

public class crypto { 

    static String IV = "AAAAAAAAAAAAAAAA"; 
    static String plaintext = "my non padded text"; 
    static String encryptionKey = "abcdef"; 

    public static void main(String[] args) 
    { 
     byte[] cipher = encrypt(plaintext); 
     String decrypted = decrypt(cipher); 
    } 

    protected static String covertto16Byte(String plainText) 
    { 
     while(plainText.length()%16 != 0) 
      plainText += "\0";   
     return plainText; 
    } 

    protected static String removePadding(String plainText) 
    { 
     return plainText.replace("\0",""); 
    } 

    protected static byte[] encrypt(String plainText) 
    { 
     try 
     { 
      String _plaintText_16 = covertto16Byte(plainText); 
      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE"); 
      SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES"); 
      cipher.init(Cipher.ENCRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8"))); 
      return cipher.doFinal(_plaintText_16.getBytes("UTF-8")); 
     } catch (Exception ex) 
     { 
      //catch mechanism 
      return null; 
     } 
    } 

    protected static String decrypt(byte[] cipherText) 
    { 
     try 
     { 
      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding", "SunJCE"); 
      SecretKeySpec key = new SecretKeySpec(encryptionKey.getBytes("UTF-8"), "AES"); 
      cipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(IV.getBytes("UTF-8"))); 
      return removePadding(new String(cipher.doFinal(cipherText), "UTF-8")); 
     } catch (Exception ex) 
     { 
      //catch mechanism 
      return null; 
     } 
    }  
} 
0

Вы должны Base64 зашифрованного содержимого. Кстати, это обычная техника.

Я предполагаю, что проблема с клиентом была не в формате Base64, а в том, что Base64 не является (сильным) шифрованием.

1

Если клиент не любит Base64, попробуйте Base32 или Base16 (= hex). Они менее распространены, но хорошо определены альтернативы Base64.

Вы также можете узнать, почему клиент не хочет, чтобы вы использовали Base64.

+0

клиент doesn Не хочу кодирования, они хотят ENCRYPTION, и я ничего не знаю о шифровании ...Я в основном должен зашифровать пароль, однажды введенный в текстовый файл. Я подбираю его, кодирую и сохраняю. И позже используется кодированный пароль. – Moon

+0

Если пароль сохраняется только для проверки входа в систему, то хеш его с растяжкой и солью, не шифруйте. Если пароль будет сохранен для использования в другой системе, необходимо будет извлечь фактический пароль, а затем зашифровать его с помощью AES/CBC/PKCS7 и сэкономить отдельный IV для использования с каждым паролем. Посмотрите на другие ответы здесь о AES и спросите еще раз, если вам нужна помощь. – rossum

1

так, в принципе, вы не знаете о шифровании и есть проблема, что ваш клиент хочет шифрования

ок, быстрый HeadsUp:

кодирование: преобразование вход на выход, который содержит идентичную информацию, но в другом представлении ... ех: 1,2,3 -> а, Ь, с

, как вы можете видеть, что вывод выглядит по-разному, но имеет ту же самую информацию

пожалуйста, обратите внимание, что никакой секретной информации не надо шифровать/де Код

шифрования: может выглядеть на первый взгляд, но здесь нужны некоторые секреты ... шифрование занимает 2 входа ... секретные и входные данные

полученный вывод может быть расшифрованы, но только если у вас есть соответствующий секрет

Если ваш клиент хочет, чтобы вы что-то зашифровали, убедитесь, что вещь может быть представлена ​​в виде байтов ... шифрование строки ... не хорошо ... шифрование строки, которая была преобразована в < вставить произвольное байтовое кодирование здесь, например unicode> ... ok

e ncryptions обычно обрабатывают байт (давайте не будем заботиться о исторических шифров здесь)

, когда вы решите для шифрования/шифровать вы должны знать, что есть по существу две различные группы: symetric и Асимметричная

symetric: тот же ключ (прочитайте секрет), который вы используете для шифрования, потребуется для дешифрования

асимметричный: существуют ключевые пары, состоящие из открытой и закрытой частей (общедоступный/закрытый ключ), для использования которой используется открытая часть, частная часть используется для дешифрования ...не имеет смысла, если вы не имеете разные партии, которые должны обмениваться ключами

асимметричных шифров, как правило, используется для шифрования расшифровки ключей для symetric шифров, потому что они медленны, а symetric шифры обычно БЫСТРО

асимметричных шифров не предназначены для шифровать большие объемы данных

symetric шифры предназначены для объемных данных

если ваша цель просто сохранить информацию, зашифрованную в то время как она лежит вокруг на жестком диске, symetric шифра является то, что вы хотите

вам понадобится ключ для шифрования, который будет работать ... и ... у вас возникнет проблема с его хранением ... так что если вы можете, введите пользователя достаточно сложным паролем ... используйте пароль и функцию PBKDF2 с достаточно большим количеством итераций (достаточно высокий = увеличить это число до тех пор, пока процесс не займет всего несколько секунд, если вам нужно только это при запуске, или пока ваши пользователи не начнут жаловаться на задержку), чтобы сделать двоичный ключ из пароль.

использовать этот ключ для AES в режиме GCM (symetric шифр)

шифр будет хотеть что-то под названием IV или вектор инициализации ...

ХВ не секрет, вы можете предварять эту вещь к вашему ciphertext как текстовая информация iv должен быть размером одного блока вашего шифра, поэтому в случае AES 128 бит = 16 байт , поэтому ваш IV при шифровании является 16-байтовым (уникальным) случайным числом (это означает, что вы не может использовать IV раз в два или более: продолжать использовать IV и при получении нового, проверить, если он уже сохранен, если да, то начальное поколение IV, если нет, сохраните его, а затем используйте i т)

при расшифровке, читать предваряется читаемых IV из файла (первый 16 байт)

, если вы просто хотите сохранить шифрованный на диске, записать его в бинарный файл

, если файл должен содержать только печатный текст, применяя кодировку типа base16/32/64, прежде чем записывать свои байты в файл и декодировать в массив байтов перед расшифровкой (если ваши данные слишком велики для этого, тогда вам придется найти/написать поток обертка, которая добавит/разделит кодировку для вас)

+0

Хорошее резюме. Важно отметить, что IV ** должен быть уникальным и непредсказуемым для каждого сообщения, зашифрованного одним и тем же ключом. AES-GCM - это, по существу, режим CTR с функцией Galois для обеспечения тега аутентификации, а использование CTR с повторным IV/nonce абсолютно разрушает безопасность. – Andy

+0

, что подразумевалось под «случайным числом», но да, я думаю, что я должен был указать это явно – DarkSquirrel42

Смежные вопросы