2016-12-27 2 views
0

Я искал почти все темы здесь по этому вопросу, но я до сих пор не могу понять, что не так. Я создал 3 EditText на моем Android-приложении: EditText, где вы вставляете ключ/пароль для шифрования и дешифрования; EditText2 где показан зашифрованный текст; EditText3, где показан расшифрованный текст.Blowfish на студии android для шифрования/дешифрования

Поскольку это еще ранний тест, я поместил сообщение или строку в Crypt как переменную в приложении.

Проблема в том, что шифрование дает что-то вроде алгоритма blowfish, поэтому проблем нет (он заканчивается на 2 ==, поэтому я думаю, что он работает правильно). Я также пытался декодировать строку перед расшифровкой или использовать необработанный byte[] из шифрования без какого-либо хорошего результата. Дешифрование не возвращает исходный текст String, вместо этого дает нечто большее, чем зашифрованный текст. У меня нет предпочтения в режиме blowfish, поэтому я начал легко, как Blowfish/CFB/NoPadding.

str_key, str2 и str3 объявлены публичными пока. str2 установит текст для поля EditText2 и str3 установит текст для поля EditText3. Пример вывода: Example of output generated from the app

Вот код:

public void encrypt(){ 
    //encrypt 
    EditText mEdit = (EditText)findViewById(R.id.editText); 
    str_key = (String) mEdit.getText().toString(); 

    int iterationCount = 1000; 
    int keyLength = 256; 
    int saltLength = keyLength/8; 

    SecureRandom random = new SecureRandom(); 
    byte[] salt = new byte[saltLength]; 
    random.nextBytes(salt); 
    KeySpec keySpec = new PBEKeySpec(str_key.toCharArray(), salt, 
      iterationCount, keyLength); 
    SecretKeyFactory keyFactory = null; 
    try { 
     keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    byte[] keyBytes = new byte[0]; 
    try { 
     keyBytes = keyFactory.generateSecret(keySpec).getEncoded(); 
    } catch (InvalidKeySpecException e) { 
     e.printStackTrace(); 
    } 
    SecretKey key = new SecretKeySpec(keyBytes, "Blowfish"); 

    Cipher cipher = null; 
    try { 
     cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding"); 
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } 
    if (cipher == null || key == null) { 
     //throw new Exception("Invalid key or cypher"); 
     str2="error"; 
    } 
    else { 
     byte[] iv = new byte[cipher.getBlockSize()]; 
     random.nextBytes(iv); 
     IvParameterSpec ivParams = new IvParameterSpec(iv); 
     try { 
      cipher.init(Cipher.ENCRYPT_MODE, key,ivParams); 
     } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { 
      e.printStackTrace(); 
     } 


     try { 
      raw = cipher.doFinal(message.getBytes("UTF-8")); 
     } catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) { 
      e.printStackTrace(); 
     } 
     str2 = Base64.encodeToString(raw,Base64.DEFAULT); 

    } 


} 

Вот функция расшифровывать:

public void decrypt(){ 
      int iterationCount = 1000; 
      int keyLength = 256; 
      int saltLength = keyLength/8; 
      SecureRandom random = new SecureRandom(); 
      byte[] salt = new byte[saltLength]; 
      random.nextBytes(salt); 
      KeySpec keySpec = new PBEKeySpec(str_key.toCharArray(), salt, iterationCount, keyLength); 
      SecretKeyFactory keyFactory = null; 
      try { 
       keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
       } catch (NoSuchAlgorithmException e) { 
       e.printStackTrace(); 
       } 
       byte[] keyBytes = new byte[0]; 
       try { 
       keyBytes = keyFactory.generateSecret(keySpec).getEncoded(); 
       } catch (InvalidKeySpecException e) { 
        e.printStackTrace(); 
       } 
       SecretKey key = new SecretKeySpec(keyBytes, "Blowfish"); 



    Cipher cipher2 = null; 
    try { 
     cipher2 = Cipher.getInstance("Blowfish/CBC/PKCS5Padding"); 
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { 
     e.printStackTrace(); 
    } 
    iv = new byte[cipher2.getBlockSize()]; 
    random.nextBytes(iv); 
    IvParameterSpec ivSpec = new IvParameterSpec(iv); 
    try { 
     cipher2.init(Cipher.DECRYPT_MODE, key, ivSpec); 
    } catch (InvalidKeyException | InvalidAlgorithmParameterException e) { 
     e.printStackTrace(); 
    } 
    byte[] decryptedBytes = null; 
    byte[] app= Base64.decode(str2,Base64.DEFAULT); 

    try { 
     decryptedBytes = cipher2.doFinal(app); 
    } catch (IllegalBlockSizeException | BadPaddingException e) { 
     e.printStackTrace(); 
    } 


    str3 = Base64.encodeToString(decryptedBytes,Base64.DEFAULT); 
} 

ответ

2

Вы закодировать зашифрованный результат base64, но тогда, когда вы расшифровать, вы возьмите простые байты этого base64. Сначала вы должны сначала декодировать base64, чтобы получить фактический байтовый массив зашифрованного текста, а затем расшифровать его.

Вы также получаете свой ключ непосредственно из массива байтов UTF8, что очень плохо подходит для этого. Вместо этого вы должны использовать KDF. PBKDF2 наиболее часто используется здесь.

Способ, которым вы генерируете IV (не генерируя его вообще), также очень плохой. Он должен быть случайным образом сгенерирован и добавлен к зашифрованному тексту. Это не обязательно быть секретным, просто непредсказуемым.

Наконец, вы не используете HMAC вообще, поэтому любой может изменить зашифрованный текст, и вы не знаете.

+0

Благодарим вас за ответ. Я также попытался использовать base64-декодирование, а также использовать исходный «предварительно» кодированный массив байтов для дешифрования без результата. Можете ли вы привести пример того, что я должен делать? Должен ли я просто менять UTF-8 с KDF.PBKDF2? Я также пробовал генерировать IV как: IvParameterSpec ivSpec = new IvParameterSpec (keySpec.getEncoded()); // в функции дешифрования; , но я получаю ошибку времени выполнения. Можете ли вы привести мне пример для этого? – Micene

+0

Как я могу использовать HMAC, чтобы избежать изменения cipherText? – Micene

+1

Это все, что вы можете найти в Google, вы ничего не узнаете, если я просто напишу код для вас! Если вы попробовали его даже с расшифровкой base64, вы просто просто сделали что-то не так. Попробуйте отредактировать код в своем оригинальном посте до того, что вы попробовали, и я помогу вам оттуда. –

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