Шифрование AES реализовано в режиме ECB, но не соответствует требованиям безопасности. Как реализовать режим CBC

Я реализовал шифрование AES в Java, но команда не принимает этот алгоритм, поскольку он реализован в режиме ECB, который не соответствует требованиям безопасности. Я очень плохо знаком с требованиями к криптографии и безопасности.

Может кто-нибудь, пожалуйста, помогите мне изменить алгоритм в режиме CBC. Я приложил свой код, реализованный в режиме ECB.

public String encrypt(String plainPwd)
{
    byte[] outputBytes = new byte[] {};
    String returnString = "";
    try
    {
        byte[] raw = "XXXXX@XXXXXX.XXX".getBytes("UTF-8");

        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

        outputBytes = cipher.doFinal(plainPwd.getBytes("UTF-8"));
        if (null != outputBytes)
        {
            returnString = Base64Encrypter.getInstance().encode(outputBytes);
        }
        return returnString.trim();

    }
    catch (Exception e)
    {
        System.out.println(e);
    }

    return new String(outputBytes).trim();
}

public String decrypt(String encryptedPwd)
{
    byte[] outputBytes = new byte[] {};
    try
    {
        byte[] raw = "XXXXX@XXXXXX.XXX".getBytes("UTF-8");

        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);

        byte[] inputBytes = Base64Encrypter.getInstance().decode(encryptedPwd);
        if (null != inputBytes)
        {
            outputBytes = cipher.doFinal(inputBytes);
        }
    }
    catch (Exception e)
    {
        System.out.println(e);
    }

    return new String(outputBytes).trim();
}

Ранний ответ будет высоко оценен. заранее спасибо

3 ответа

Изменить строку запроса с AES в AES/CBC/PKCS5PADDING и добавить iv. Хотя заполнение не является специфичным для CBC, полезно явно определить все параметры и, за небольшим исключением, требуется заполнение.

Для iv генерируют криптографически безопасное случайное число блоков размером (16 байтов для AES). Для того, чтобы сделать iv доступным для расшифровки, обычной практикой является добавление его к зашифрованным данным, он не должен быть секретным.

AES имеет около 6 различных режимов шифрования. Важно, чтобы вы использовали правильный режим для приложения, для которого вы его используете. как говорит @eckes, ECB подходит для небольших объемов данных, где полезен произвольный доступ к шифрованию / дешифрованию. Недостаток ECB состоит в том, что один и тот же вход будет иметь одинаковый выход, поэтому злоумышленник может видеть шаблоны и может перепроектировать их, если количество практических значений ограничено.

Узнайте, как выбрать режим шифрования AES, чтобы узнать, как правильно выбрать режим работы.

Если ваши данные короткие и случайный ECB может быть приемлемым (по крайней мере, не хуже, чем CBC). Но, скорее всего, это хорошая идея - даже не пытаться понять это правильно.

Имейте в виду, CBC также не предлагает защиту целостности. Лучше использовать дополнительный HMAC или выделенный режим для упаковки секретов (AESKeywrap) или использовать режим с проверкой подлинности (AES/GCM). (и это не только вопрос избегания модификаций, но и закрывает класс атак на защиту конфиденциальности протоколов).

Если данные не случайны / предсказуемы, вам нужно использовать режим, который также использует IV. В случае CBC Java выберет случайный IV, если не указан.

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

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
byte[] iv = cipher.getIV(); // randomly filled.
...

// on decrypt specify this IV again
cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(iv));

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

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