Я добавляю поддержку 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, не работает.