BouncyCastle NoSuchProviderException, хотя это зависимость от Maven

Я пытаюсь создать существующий проект JavaEE с помощью Wildfly Swarm, но постоянно сталкиваюсь с проблемой в одной из моих библиотек. Предполагается загрузить с сервера публичный ключ в формате PEM и использовать его для проверки подписей. Однако я продолжаю получать это:

2017-06-08 20:55:59,229 ERROR [stderr] (default task-3) java.security.NoSuchProviderException: no such provider: BC
2017-06-08 20:55:59,234 ERROR [stderr] (default task-3)     at sun.security.jca.GetInstance.getService(GetInstance.java:83)
2017-06-08 20:55:59,238 ERROR [stderr] (default task-3)     at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
2017-06-08 20:55:59,238 ERROR [stderr] (default task-3)     at java.security.KeyFactory.getInstance(KeyFactory.java:211)
2017-06-08 20:55:59,239 ERROR [stderr] (default task-3)     at enterprises.mccollum.wmapp.ssauthclient.PublicKeySingleton.loadPubKey(PublicKeySingleton.java:83)
2017-06-08 20:55:59,239 ERROR [stderr] (default task-3)     at enterprises.mccollum.wmapp.ssauthclient.PublicKeySingleton.init(PublicKeySingleton.java:57)

Код, который вызывает проблемы, находится здесь:

PublicKeySingleton.java snippet:
81:    PemObject pemPubKey = ldPemFromServer();
82:    if(pemPubKey != null){
83:    KeyFactory kf = KeyFactory.getInstance("RSA", BouncyCastleProvider.PROVIDER_NAME);
84:    PublicKey lPubKey =  kf.generatePublic(new X509EncodedKeySpec(pemPubKey.getContent()));
85:    Logger.getLogger(SSAuthClient.SUBSYSTEM_NAME).log(Level.INFO, "Read public key from url successfully");
86:    return lPubKey;

Вот pom.xml для библиотеки с приведенным выше кодом:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>enterprises.mccollum.wmapp</groupId>
    <artifactId>ssauthclient</artifactId>
    <version>1.0.5-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>enterprises.mccollum.utils</groupId>
            <artifactId>genericentityejb</artifactId>
            <version>1.0.5</version>
        </dependency>
        <dependency>
            <groupId>enterprises.mccollum.jee</groupId>
            <artifactId>urlutils</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.56</version>
            <!-- Tried changing the version to 1.52, as used by Swarm itself, but to no avail -->
        </dependency>
    </dependencies>
    <build>
        <finalName>ssauthclient</finalName>
        <extensions>
            <extension>
                <groupId>org.apache.maven.wagon</groupId>
                <artifactId>wagon-webdav</artifactId>
                <version>1.0-beta-2</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-javadoc-plugin</artifactId>
                <executions>
                    <execution>
                    <id>attach-javadocs</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

А вот pom.xml для проекта Swarm:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>ie.countries.cdn</groupId>
    <artifactId>cbook</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <version.wildfly.swarm>2017.6.0</version.wildfly.swarm>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.wildfly.swarm</groupId>
                <artifactId>bom</artifactId>
                <version>${version.wildfly.swarm}</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>enterprises.mccollum.wmapp</groupId>
            <artifactId>ssauthclient</artifactId>
            <version>1.0.5-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>6.1</version>
        </dependency>
        <dependency>
            <groupId>org.ocpsoft.rewrite</groupId>
            <artifactId>rewrite-servlet</artifactId>
            <version>3.4.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.ocpsoft.rewrite</groupId>
            <artifactId>rewrite-config-prettyfaces</artifactId>
            <version>3.4.1.Final</version>
        </dependency>
        <dependency>
            <groupId>org.primefaces.themes</groupId>
            <artifactId>bootstrap</artifactId>
            <version>1.0.10</version>
        </dependency>
        <dependency>
            <groupId>org.omnifaces</groupId>
            <artifactId>omnifaces</artifactId>
            <version>2.6.2</version>
        </dependency>
        <!-- WildFly Swarm Fractions -->
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>cdi</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>ejb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>management</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>datasources</artifactId>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.195</version>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>management-console</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>cdi-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>jsf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.wildfly.swarm</groupId>
            <artifactId>jaxrs</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>cbook</finalName>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>META-INF/persistence.xml</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <executions>
                    <execution>
                        <id>attach-sources</id>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.wildfly.swarm</groupId>
                <artifactId>wildfly-swarm-plugin</artifactId>
                <version>${version.wildfly.swarm}</version>

                <executions>
                    <execution>
                        <goals>
                            <goal>package</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Я очень смущен тем, почему это не сработает, особенно когда и uberjar, и war, созданные mvn package, включают зависимость поставщика bouncycastle в виде jar.

Что происходит не так? Это ошибка в Swarm или мне не хватает трюка, который мне нужно сделать, чтобы заставить его работать?


person KG6ZVP    schedule 09.06.2017    source источник
comment
рой пом, похоже, не содержит зависимости от надувного замка.   -  person Andrei Epure is hiring    schedule 09.06.2017
comment
но он содержит зависимость (ssauthclient), которая (этот pom является первым в вопросе)   -  person KG6ZVP    schedule 09.06.2017


Ответы (2)


Поставщик не находится в JVM по умолчанию (вы можете проверить список поставщиков в $JAVA_HOME/jre/lib/security/java.security или с помощью Security.getProviders()).

Вы должны добавить его, используя класс Security:

import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

Security.addProvider(new BouncyCastleProvider());

Некоторые люди предпочитают проверять, существует ли уже провайдер, и добавлять только в том случае, если его нет:

// if provider is not present, add it
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
    // insert at specific position
    Security.insertProviderAt(new BouncyCastleProvider(), 1);
}

Разница между методами выше заключается в том, что addProvider добавляет провайдера в конец списка провайдеров (тот, который возвращает getProviders), а insertProviderAt добавляет его в указанную позицию (а остальные сдвигаются).

Другой вариант — отредактировать файл $JAVA_HOME/jre/lib/security/java.security и добавить провайдера в нужное место:

security.provider.2=org.bouncycastle.jce.provider.BouncyCastleProvider

Более подробную информацию об этом методе можно найти здесь.

person Community    schedule 09.06.2017
comment
Чем он отличается от обычного экземпляра Wildly? Я могу запустить то же самое приложение на обычном сервере приложений Java EE, не создавая дополнительных проблем. Или это не должно работать и это баг? - person KG6ZVP; 09.06.2017
comment
Некоторые серверы могут уже загружать BouncyCastle при запуске или уже где-то его настроить. Но не гарантируется, что все серверы будут это делать, поэтому вам придется добавить это вручную. Вы можете использовать метод getProvider, чтобы проверить, загружен ли он уже, и добавить его соответствующим образом. - person ; 09.06.2017
comment
Спасибо. Я исправил библиотеку, чтобы сделать это, и теперь она работает. - person KG6ZVP; 09.06.2017

Вам необходимо установить BouncyCastle в качестве провайдера. Два способа: сначала в чистой java:

Security.addProvider(new BouncyCastleProvider());

Второй метод статически как запись в файле java.security:

security.provider.N=org.bouncycastle.jce.provider.BouncyCastleProvider

Очевидно, вам это нужно в вашем пути к классам.

person JEY    schedule 09.06.2017