«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, поэтому его легко импортировать и запускать как есть.