Спецификация ключа Wildfly 10 BouncyCastleCrypto ECDSA не распознана

Я добавляю поддержку FIDO U2F в свое J2EE-приложение (которое в основном обеспечивает вход в систему с помощью аппаратного токена). Я использую библиотеку от yubico, u2flib-server-core, которая обрабатывает криптографические операции в протоколе с использованием BouncyCastleCrypto. Однако при декодировании открытого ключа из постоянного хранилища я продолжаю получать исключение с сообщением

"ключевая спецификация не распознана"

Я сузил проблему до этой функции из библиотеки

public PublicKey decodePublicKey(byte[] encodedPublicKey) throws U2fBadInputException {
        try {
            X9ECParameters curve = SECNamedCurves.getByName("secp256r1");
            ECPoint point;
            try {
                point = curve.getCurve().decodePoint(encodedPublicKey);
            } catch (RuntimeException e) {
                throw new U2fBadInputException("Could not parse user public key", e);
            }

            return KeyFactory.getInstance("ECDSA").generatePublic(
                    new ECPublicKeySpec(point,
                            new ECParameterSpec(
                                    curve.getCurve(),
                                    curve.getG(),
                                    curve.getN(),
                                    curve.getH()
                            )
                    )
            );
        } catch (GeneralSecurityException e) { //This should not happen
            throw new RuntimeException(e);
        }
    }

Метод generatePublic генерирует исключение, которое перехватывается и повторно генерируется как RuntimeException.

Я проверил, что KeyFactory.getInstance возвращает KeyFactory от поставщика BC. Запуск этого кода вне Wildfly работает отлично. (Мне пришлось поместить bcprov-ext-jdk15on-154.jar в /lib/ext java).

Я уже пытался обновить модуль wildfly для bouncycastle, в настоящее время я добавил все 6 банок, опубликованных на http://www.bouncycastle.org/latest_releases.html

Интересная часть из трассировки стека

java.security.spec.InvalidKeySpecException: key spec not recognised
    at org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePublic(Unknown Source)
    at org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi.engineGeneratePublic(Unknown Source)
    at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
    at com.yubico.u2f.crypto.BouncyCastleCrypto.decodePublicKey(BouncyCastleCrypto.java:60)
    at com.yubico.u2f.data.messages.key.RawAuthenticateResponse.checkSignature(RawAuthenticateResponse.java:64)
    at com.yubico.u2f.U2fPrimitives.finishAuthentication(U2fPrimitives.java:153)
    at com.yubico.u2f.U2F.finishAuthentication(U2F.java:116)
    at com.yubico.u2f.U2F.finishAuthentication(U2F.java:90)

Надеюсь, кто-нибудь может мне помочь :-) Заранее спасибо

EDIT: я пробовал этот код с другими режимами и похоже, что ни одно событие не распознается. Использование EC Исключение отличается тем, что оно использует другого поставщика, однако настройка списка поставщиков, в котором BC находится наверху, приводит к тому же исключению, о котором я упоминал.

EDIT Я думаю, что это может быть какая-то проблема с загрузкой классов, поэтому я включил подробное ведение журнала, и вот интересные журналы.

[Loaded org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi$ECDSA from file:/home/martin/java/jdk1.8.0_45/jre/lib/ext/bcprov-jdk15on-154.jar]
[Loaded org.bouncycastle.jce.spec.ECKeySpec from jar:file:/opt/wildfly-10.0.0.Final/modules/system/layers/base/org/bouncycastle/main/bcprov-jdk15on-1.52.jar!/]

KeyFactorySpi и ECKeySpec поступают из двух разных банок (загрузчиков классов?), поэтому instanceof, используемый в KeyFactory, не работает.


person Martin Hlavňa    schedule 27.03.2016    source источник


Ответы (1)


Наконец нашел проблему :-)

Когда я включил подробное ведение журнала загрузчиков классов, я обнаружил, что KeySpec исходит от другого загрузчика классов, такого как KeyFactorySpi, который проверял экземпляр этого KeySpec. Это проблема, которую я вызвал во время решения этой проблемы. Поскольку wildfly 10 поставляется с модулем BouncyCastle, от которого зависит RestEasy, он загружается. Библиотека Hovever, которую я использовал, также поставляла некоторые классы BouncyCastle.

Все, что мне нужно было сделать, это создать jboss-deployment-structure.xml со следующим содержимым

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.1">
    <deployment>
        <dependencies>
            <module name="org.bouncycastle" />
        </dependencies>
    </deployment>
</jboss-deployment-structure>

Это позволило мне использовать модуль wildfly для BouncyCastle. Однако, когда я сделал это, я уже пытался поместить BouncyCastle в lib/ext/ JRE, с которым я использовал для запуска сервера. Это вызвало точно такую ​​же ошибку с другой причиной :-)

Подводя итог, при использовании BouncyCastle с wildfly 10 вы должны убедиться в следующем:

  1. Создайте файл jboss-deployment-structure.xml с зависимостью от модуля Wildfly } или, в качестве альтернативы, вы можете использовать для этого файл MANIFEST.mf|
  2. Убедитесь, что у вас нет провайдера BouncyCastle в lib/ext/JRE, который вы используете.
  3. Если вы динамически добавляете поставщика JCE BouncyCastle, вам также необходимо использовать файлы политик JCE Unlimited (если вы, конечно, можете по закону)

Надеюсь, это поможет кому-то в будущем :-)

person Martin Hlavňa    schedule 28.03.2016
comment
Большое спасибо за решение! - person Jakub Dyszkiewicz; 19.05.2017