«1. Обзор

В этой статье мы рассмотрим библиотеку Jasypt (Java Simplified Encryption).

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

2. Использование простого шифрования

Представьте, что мы создаем веб-приложение, в котором пользователь отправляет личные данные учетной записи. Нам нужно хранить эти данные в базе данных, но хранить обычный текст было бы небезопасно.

Один из способов справиться с этим — хранить зашифрованные данные в базе данных, а при извлечении этих данных для конкретного пользователя расшифровывать их.

Чтобы выполнить шифрование и дешифрование с использованием очень простого алгоритма, мы можем использовать класс BasicTextEncryptor из библиотеки Jasypt:

BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
String privateData = "secret-data";
textEncryptor.setPasswordCharArray("some-random-data".toCharArray());

Затем мы можем использовать метод encrypt() для шифрования обычного текста:

String myEncryptedText = textEncryptor.encrypt(privateData);
assertNotSame(privateData, myEncryptedText);

~ ~~ Если мы хотим сохранить личные данные для данного пользователя в базе данных, мы можем сохранить myEncryptedText без нарушения каких-либо ограничений безопасности. Если мы хотим расшифровать данные обратно в обычный текст, мы можем использовать метод decrypt():

String plainText = textEncryptor.decrypt(myEncryptedText);
 
assertEquals(plainText, privateData);

Мы видим, что расшифрованные данные равны обычным текстовым данным, которые были ранее зашифрованы.

3. Одностороннее шифрование

Предыдущий пример не является идеальным способом выполнения аутентификации, когда мы хотим сохранить пароль пользователя. В идеале мы хотим зашифровать пароль без возможности его расшифровки. Когда пользователь пытается войти в наш сервис, мы шифруем его пароль и сравниваем его с зашифрованным паролем, который хранится в базе данных. Таким образом, нам не нужно работать с открытым текстовым паролем.

Мы можем использовать класс BasicPasswordEncryptor для выполнения одностороннего шифрования:

String password = "secret-pass";
BasicPasswordEncryptor passwordEncryptor = new BasicPasswordEncryptor();
String encryptedPassword = passwordEncryptor.encryptPassword(password);

Затем мы можем сравнить уже зашифрованный пароль с паролем пользователя, который выполняет процесс входа в систему без необходимости расшифровки пароля, т.е. уже сохранены в базе данных:

boolean result = passwordEncryptor.checkPassword("secret-pass", encryptedPassword);

assertTrue(result);

4. Настройка алгоритма шифрования

Мы можем использовать более надежный алгоритм шифрования, но нам нужно не забыть установить файлы политики юрисдикции неограниченной силы Java Cryptography Extension (JCE) для нашей JVM ( инструкции по установке включены в загрузку).

В Jasypt мы можем использовать надежное шифрование с помощью класса StandardPBEStringEncryptor и настроить его с помощью метода setAlgorithm():

StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
String privateData = "secret-data";
encryptor.setPassword("some-random-passwprd");
encryptor.setAlgorithm("PBEWithMD5AndTripleDES");

Давайте установим алгоритм шифрования PBEWithMD5AndTripleDES.

Далее процесс шифрования и дешифрования выглядит так же, как и предыдущий, с использованием класса BasicTextEncryptor:

String encryptedText = encryptor.encrypt(privateData);
assertNotSame(privateData, encryptedText);

String plainText = encryptor.decrypt(encryptedText);
assertEquals(plainText, privateData);

5. Использование многопоточного дешифрования

Когда мы работаем на многоядерной машине мы хотим обрабатывать обработку дешифрования параллельно. Чтобы добиться хорошей производительности, мы можем использовать PooledPBEStringEncryptor и API setPoolSize() для создания пула дайджестов. Каждый из них может использоваться разными потоками параллельно:

PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
encryptor.setPoolSize(4);
encryptor.setPassword("some-random-data");
encryptor.setAlgorithm("PBEWithMD5AndTripleDES");

Рекомендуется устанавливать размер пула равным количеству ядер машины. Код для шифрования и дешифрования такой же, как и предыдущие.

6. Использование в других платформах

И последнее замечание: библиотека Jasypt может быть интегрирована со многими другими библиотеками, включая, конечно, Spring Framework.

Нам нужно только создать конфигурацию, чтобы добавить поддержку шифрования в наше приложение Spring. И если мы хотим хранить конфиденциальные данные в базе данных и используем Hibernate в качестве среды доступа к данным, мы также можем интегрировать с ней Jasypt.

Инструкции по интеграции этих, а также некоторых других фреймворков можно найти в разделе «Руководства» на домашней странице Jasypt.

7. Заключение

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

«Реализацию всех этих примеров и фрагментов кода можно найти в проекте GitHub — это проект Maven, поэтому его легко импортировать и запускать как есть.