Я не разбираюсь в криптографии и рву на себе волосы. У меня есть следующая (упрощенная) настройка и код.
Настройка Maven для использования BouncyCastle
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>1.78.1</version>
</dependency>
Код
try {
PublicKey serverPubKey = CertUtil.getPubKey(new File(cert_fp));
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding");
OAEPParameterSpec specs = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT);
cipher.init(1, serverPubKey, specs);
} catch (CertificateException | NoSuchPaddingException | InvalidKeyException |
InvalidAlgorithmParameterException | NoSuchAlgorithmException e) {
LOGGER.severe("Cannot create encryption cipher. " + e);
}
При работе в Windows (Java 17) все работает. При работе в Red Hat 8 (openjdk 17) я получил
Cannot create encryption cipher. java.security.NoSuchAlgorithmException: Cannot find any provider supporting RSA/ECB/OAEPPadding
Дело в том, что раньше это работало и на Red Hat. Сейчас я немного не понимаю, что могло вызвать ошибку. Я проверил команду для ее запуска, и в пути к классам находится jumpycastle.
Я добавил несколько кодов для проверки поставщиков, и они выглядят одинаково как в Windows, так и в Linux.
Set<String> algs = new TreeSet<>();
for (Provider provider : Security.getProviders()) {
provider.getServices().stream()
.filter(s -> "Cipher".equals(s.getType()))
.map(Service::getAlgorithm)
.forEach(algs::add);
}
algs.forEach(System.out::println);
Выход
AES/CBC/NoPadding
AES/CBC/PKCS5Padding
AES/CTR/NoPadding
AES/ECB/NoPadding
AES/ECB/PKCS5Padding
AES/GCM/NoPadding
AES_128/CBC/NoPadding
AES_128/ECB/NoPadding
AES_128/GCM/NoPadding
AES_192/CBC/NoPadding
AES_192/ECB/NoPadding
AES_192/GCM/NoPadding
AES_256/CBC/NoPadding
AES_256/ECB/NoPadding
AES_256/GCM/NoPadding
ARCFOUR
ChaCha20-Poly1305
DES/CBC/NoPadding
DES/CBC/PKCS5Padding
DES/ECB/NoPadding
DES/ECB/PKCS5Padding
DESede/CBC/NoPadding
DESede/CBC/PKCS5Padding
DESede/ECB/NoPadding
DESede/ECB/PKCS5Padding
PBEWithHmacSHA1AndAES_128
PBEWithHmacSHA1AndAES_256
PBEWithHmacSHA224AndAES_128
PBEWithHmacSHA224AndAES_256
PBEWithHmacSHA256AndAES_128
PBEWithHmacSHA256AndAES_256
PBEWithHmacSHA384AndAES_128
PBEWithHmacSHA384AndAES_256
PBEWithHmacSHA512AndAES_128
PBEWithHmacSHA512AndAES_256
RSA/ECB/NoPadding
RSA/ECB/PKCS1Padding
Что мне не хватает? Что я могу попробовать? Мне нужно использовать «RSA/ECB/OAEPPadding».
Спасибо
Я использую openjdk 17. Я попробовал OAEPWithSHA-256AndMGF1Padding
и все равно получаю NoSuchAlgorithmException
.
По какой-то причине поставщик SunJCE недоступен. Попробуйте добавить провайдера BouncyCastle: Security.addProvider(new BouncyCastleProvider());
как здесь jdoodle.com/ia/16Ld.
Вот и все. Это тонкая часть, которую я потерял в коде. Большое спасибо. Я не знаю, как сделать ваш комментарий ответом.
Я планировал настроить виртуальную машину Virtualbox с RHEL8, чтобы проверить это, но не мог понять, как это сделать, не предоставив Redhat чрезмерное количество личной информации.
Вам необходимо явно зарегистрировать криптопровайдера Bouncy Castle при запуске вашего приложения, например:
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
Он определенно включает в себя «RSA/ECB/OAEPPadding».
Поставщик Bouncycastle вообще не нужен.
Какую версию Java вы используете? Также попробуйте с
OAEPWithSHA-256AndMGF1Padding
.