Blowfish на андроид студии для шифрования / дешифрования

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

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

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

str_key, str2 а также str3 объявлены публичными на данный момент. str2 установит текст для EditText2 поле и str3 установит текст для EditText3 поле. Пример вывода: Пример вывода, сгенерированного из приложения

Вот код:

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);
}

1 ответ

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

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

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

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

Другие вопросы по тегам