Быстрый и простой в использовании симметричный шифр для целочисленного шифрования в Java.

Что такое в Java функция шифрования для целочисленного шифрования, обладающая этими свойствами?:

  • Быстрый
  • Алгоритм с симметричным ключом
  • Простой в использовании (т.е. пара строк кода для его использования и отсутствие внешней библиотеки для включения)
  • Можно указать длину вывода (например, 20 символов)

Мне нужно использовать его только для шифрования/дешифрования целых чисел.


person Andrea    schedule 26.04.2015    source источник
comment
Для этого работает функция идентификации, она быстрая, симметричная, очень простая в использовании, и можно указать длину вывода, передав ввод заданной длины.   -  person Benjamin Gruenbaum    schedule 26.04.2015
comment
@BenjaminGruenbaum Мне нужно зашифровать целые числа, как это возможно с помощью функции идентификации?   -  person Andrea    schedule 26.04.2015
comment
Вы никогда не можете указать длину вывода. Это следует из открытого текста.   -  person Artjom B.    schedule 26.04.2015
comment
@ArtjomB. Хорошо.. Итак, позвольте мне удалить это требование.. А как насчет остальных трех?   -  person Andrea    schedule 26.04.2015


Ответы (3)


Требование отсутствия внешней библиотеки сокращает список до DES, 3DES и AES. DES и 3DES имеют размер блока 64 бита, тогда как AES имеет размер блока 128 бит. Есть разные аспекты, можно рассмотреть это.

Размер зашифрованного текста

DES и 3DES лучше всего использовать для целых чисел шириной не более 56 бит (неполной длины), потому что результатом будет один блок из 8 байтов из-за заполнения. Если вы зашифруете полное длинное значение, будет добавлен дополнительный блок заполнения.

AES всегда будет создавать 16-байтовый зашифрованный текст для любого значения типа int.

Скорость

Согласно данному анализу AES (Rijndael-128) более чем в два раза быстрее, чем DES/3DES, с большим размером ключа (более безопасным). AES может быть даже намного быстрее, чем DES или 3DES, если процессор поддерживает AES-NI. Все современные процессоры поддерживают это. Это мой текущий результат для команды openssl speed.

AES достигает 127 МБ/с для 16-байтовой полезной нагрузки, тогда как 3DES достигает только 27 МБ/с. Вот данные, которые нужно изучить.

Безопасность

Не используйте DES ни для чего серьезного, потому что он имеет только 56-битный ключ (64-битный с четностью). Стоимость грубой силы составляет 256. 3DES также не так хорош, потому что стоимость брут-форса составляет -a-meet-in-the-middle">2112. Стоимость перебора для AES составляет 2128, 2192, 2256 в зависимости от размера используемого ключа.

Код

Вероятно, используйте AES:

private final String CIPHER_NAME = "AES/ECB/PKCS5Padding";
private final String ALGORITHM_NAME = "AES"; // keySizes 128, 192, 256
// private final String CIPHER_NAME = "DES/ECB/PKCS5Padding";
// private final String ALGORITHM_NAME = "DES"; // keySize 56
// private final String CIPHER_NAME = "DESede/ECB/PKCS5Padding";
// private final String ALGORITHM_NAME = "DESede"; // keySize 168

byte[] encrypt(SecretKey key, long num) {
    BigInteger bignum = BigInteger.valueOf(num);
    Cipher cipher = Cipher.getInstance(CIPHER_NAME);
    cipher.init(Cipher.ENCRYPT_MODE, key);
    return cipher.doFinal(bignum.toByteArray());
}

long decrypt(SecretKey key, byte[] ct) {
    Cipher cipher = Cipher.getInstance(CIPHER_NAME);
    cipher.init(Cipher.DECRYPT_MODE, key);
    byte[] pt = cipher.doFinal(ct);
    BigInteger bignum = new BigInteger(pt);
    return bignum.longValue();
}

SecretKey keyGen(String algorithm, int keySize) {
    KeyGenerator keygen = KeyGenerator.getInstance(algorithm);
    keygen.init(keySize);
    return keygen.generateKey();
}

Режим работы

Здесь я использую режим ECB. Как правило, использовать его не рекомендуется. Проблема заключается в том, что шифрование одного и того же открытого текста одним и тем же ключом приводит к одному и тому же зашифрованному тексту. Это может быть неприемлемым свойством. Если это неприемлемо, то вам нужно использовать, например, режим CBC с новым случайным IV. With взорвет зашифрованный текст дополнительным блоком.

person Artjom B.    schedule 26.04.2015
comment
Я предполагаю, что целое число на самом деле означает 32-битное целое число. - person Artjom B.; 26.04.2015
comment
Я использую тип Java Long.. но ваш ответ все еще действителен, я вижу функции шифрования/дешифрования, принимающие long в качестве параметра.. не так ли? - person Andrea; 27.04.2015
comment
Во всяком случае, у меня это работает!.. Я использовал keySize = 128 бит и фиксированный SecretKey. - person Andrea; 27.04.2015
comment
эта ссылка на анализ, кажется, говорит противоположное тому, что вы утверждаете ... они пришли к выводу, что AES был самым медленным. - person Gus; 27.04.2017
comment
@Gus Я только утверждал, что AES значительно быстрее, чем 3DES, что вы можете видеть из чисел в таблицах с 1 по 3. Имейте в виду, что 3DES обеспечивает только 112-битную безопасность из-за возможности встречи посередине. AES-128 обеспечивает по крайней мере 126-битную безопасность с текущими исследованиями и в то же время быстрее. AES можно рассматривать даже намного быстрее, если мы примем набор инструкций AES-NI текущего поколения процессоров. - person Artjom B.; 27.04.2017
comment
@Gus Я добавил сравнение производительности между AES и 3DES. Я также не считаю DES или Blowfish безопасными, потому что DES имеет только 56-битную защиту, а Blowfish устарел его автором. - person Artjom B.; 27.04.2017

Если вам нужно не безопасное решение, а просто быстрое, рассмотрите шифр XOR:

int key = ...
....
int b = a ^ key;
int c = b ^ key;
assert (c == a);
person Konstantin Pavlov    schedule 01.08.2015
comment
В конкретном случае этого вопроса шифр XOR также может быть наиболее безопасным возможным решением (поскольку длина шифра идентична длине сообщения - оба они являются целыми числами - буквально невозможно расшифровать сообщение, не зная ключ). Это верно только в том случае, если зашифрованные сообщения/целые числа независимы друг от друга и не обладают общеизвестными свойствами (например, одно конкретное сообщение является очень частым). - person Virgil; 25.09.2018
comment
XOR может быть наиболее безопасным вариантом, если ключ сгенерирован случайным образом, больше, чем сообщение, и используется только один раз за время его существования. Если вы используете ключ несколько раз, вы получаете многократный блокнот, где можно вывести исходные значения. - person Artjom B.; 09.04.2020

Никогда не применяйте шифр самостоятельно, если вам нужна какая-либо безопасность. Слишком много всего может пойти не так.

Но вы можете записать свои числа в byte[] и использовать шифр, предоставленный Java, как описано в этом ответе.

person maaartinus    schedule 26.04.2015