Требование отсутствия внешней библиотеки сокращает список до 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