Как зашифровать или расшифровать с помощью Rijndael и размером блока 256 бит?

По определенным причинам мне нужно реализовать де/сжатие Rijndael с размером блока 256 бит вместо AES, который использует размер блока 128 бит (причина: данные зашифрованы в PHP с использованием Rijndael...).

Как я могу изменить размер блока для шифра?

Если я просто получу шифр с "RIJNDAEL/CFB/PKCS5Padding" и попытаюсь инициализировать IV с 256 битами, я получу исключение, потому что размер блока составляет всего 128 бит.


person Laures    schedule 10.11.2011    source источник
comment
Вероятно, вам придется убедиться, что у вас установлены неограниченные классы шифрования Java JCE. Они не являются частью типичного стандартного дистрибутива Java, потому что незаконны в некоторых странах.   -  person Romain    schedule 10.11.2011
comment
они уже есть. до сих пор не могу понять, как получить объект шифра с требуемым размером блока   -  person Laures    schedule 10.11.2011
comment
Тогда я верю, что у @GregS есть ответ. Я полагал, что Rijndael-256 был частью JCE Unlimited Providers, но я привык использовать несколько настроенную Java моей компании, для которой есть поставщик JCE, но это вполне может быть частная реализация.   -  person Romain    schedule 11.11.2011
comment
Вы должны удалить AES из названия, AES был стандартизирован только с 128-битным блоком. Безопасность Rijndael с 256-битными блоками недостаточно хорошо изучена и вполне может быть намного слабее, чем AES. Какова бы ни была причина, по которой вам пришлось использовать Rijndael с 256-битными блоками, вряд ли она была хорошей.   -  person Bruno Rohée    schedule 02.01.2012


Ответы (2)


Ни один из поставщиков Sun JCE не поддерживает ничего, кроме Rijndael со 128-битным размером блока: это алгоритм AES. Чтобы получить rijndael с 256-битным размером блока, вам придется пойти куда-то еще. Я предлагаю библиотеку Bouncycastle java. Класс RijndaelEngine имеет конструктор который принимает размер блока в битах. Большинство людей находят класс PaddedBufferedBlockCipher. быть более удобным при использовании с подходящей прокладкой, например

PaddedBufferedBlockCipher c = new PaddedBufferedBlockCipher(new RijndaelEngine(256), new PKCS7Padding());
person President James K. Polk    schedule 10.11.2011

Обратите внимание, что PHP mcrypt использует заполнение нулевым байтом, поэтому вместо new PKCS7Padding() следует использовать new ZeroBytePadding().

Ниже полная реализация с использованием CBC и RIJNDAEL 256.

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.RijndaelEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.paddings.ZeroBytePadding;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.encoders.Base64;

public static String encryptWithAesCBC(String plaintext, String key, String iv)
{
    try {
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding());
        CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key.getBytes()), iv.getBytes());
        cipher.init(true, ivAndKey);
        return new String(Base64.encode(cipherData(cipher, plaintext.getBytes())));
    } catch (InvalidCipherTextException e) {
        throw new RuntimeException(e);
    }
}

public static String decryptWithAesCBC(String encrypted, String key, String iv)
{
    try {
        byte[] ciphertext = Base64.decode(encrypted);
        PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding());

        CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key.getBytes()), iv.getBytes());
        aes.init(false, ivAndKey);
        return new String(cipherData(aes, ciphertext));
    } catch (InvalidCipherTextException e) {
        throw new RuntimeException(e);
    }
}

private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data) throws InvalidCipherTextException
{
    int minSize = cipher.getOutputSize(data.length);
    byte[] outBuf = new byte[minSize];
    int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
    int length2 = cipher.doFinal(outBuf, length1);
    int actualLength = length1 + length2;
    byte[] cipherArray = new byte[actualLength];
    for (int x = 0; x < actualLength; x++) {
        cipherArray[x] = outBuf[x];
    }
    return cipherArray;
}

 private String md5(String string)
 {
    try {
        java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
        byte[] array = md.digest(string.getBytes());
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < array.length; ++i) {
            sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString();
    } catch (java.security.NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}

При использовании CFB PaddedBufferedBlockCipher следует заменить следующим:

PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CFBBlockCipher(new RijndaelEngine(256),8), new ZeroBytePadding());
// PHP mcrypt uses a blocksize of 8 bit for CFB

Использование:

String salt = "fbhweui3497";
String key = md5(salt);
String iv = md5(md5(salt));

String encrypted = encryptWithAesCBC("text to encript", key, iv);

String decrypted = decryptWithAesCBC(encrypted, key, iv);
person Leonardo Beal    schedule 16.11.2017
comment
Не могли бы вы предоставить md5()? Строка md5 (ввод строки) { Результат строки = ввод; MessageDigest md; попробуйте { md = MessageDigest.getInstance (MD5); md.update(input.getBytes()); Хэш BigInteger = новый BigInteger(1, md.digest()); результат = хэш.toString(16); while (result.length() ‹ 32) { // 40 для SHA-1 result = 0 + result; } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } вернуть результат; } Приведенный выше метод, java.lang.IllegalArgumentException: длина ключа не 128/160/192/224/256 бит. - person Krish; 28.01.2018
comment
@Krish Я только что добавил к ответу реализацию md5. - person Leonardo Beal; 29.01.2018