Является ли поставщик xmldsig apache santuario несовместимым с поставщиком jdk?

Я создаю цифровую подпись XML точно так же, как это упоминается почти во всех найденных мной примерах:

String providerName = System.getProperty("jsr105Provider",
"org.jcp.xml.dsig.internal.dom.XMLDSigRI");

XMLSignatureFactory fac =
XMLSignatureFactory.getInstance("DOM",
(Provider) Class.forName(providerName).newInstance());
...and so on...

Мы отправляем полученный XML-файл нашему клиенту, который проверяет эту подпись. Все тесты пройдены и до сих пор все работало нормально.

В производственной системе наш клиент неожиданно отправляет обратно "цифровая подпись неверна". После перезапуска сервера приложений все кажется снова в порядке, и некоторые файлы были успешно проверены заказчиком. Но через несколько минут / часов клиент отправляет обратно "цифровая подпись неверна". Только перезапуск сервера приложений решал проблему временно.

Я выяснил, что является причиной этой проблемы, но я не понимаю этого. Где-то в приложении используется WSS4J, инициализация выглядит следующим образом (org.apache.ws.security.WSSConfig):

public static synchronized void init() {
    if (!staticallyInitialized) {
        if (addJceProviders) {
            setXmlSecIgnoreLineBreak();
            AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                public Boolean run() {
                    addXMLDSigRI(); <-- this line causes the problem
                    addJceProvider("BC", "org.bouncycastle.jce.provider.BouncyCastleProvider");
                    Security.removeProvider("STRTransform");
                    appendJceProvider(
                        "STRTransform", new org.apache.ws.security.transform.STRTransformProvider()
                    );

                    return true;
                }
            });
        }
        staticallyInitialized = true;
    }
}

addXMLDsigRI () добавляет провайдера ApacheXMLDSig на место 2, когда его нет в текущей конфигурации провайдера (java.security). Поставщик XMLDSig jdk по умолчанию находится на месте 8.

После инициализации WSS4J каким-то образом меняется создание цифровой подписи xml, и клиент говорит, что "цифровая подпись неверна".

Я могу воспроизвести ошибку клиента, если вручную зарегистрирую провайдера ApacheXMLDSig на месте 2. Если я добавлю провайдера на место 10(после провайдера jdk), он снова заработает.

Версии:

  • XML Security 1.5.6
  • wss4j 1.6.10
  • jdk1.7.0_13
  • сервер приложений Tomcat 7

Я явно использую провайдера jdk: org.jcp.xml.dsig.internal.dom.XMLDSigRI

Почему регистрация провайдера apache "разрушает" функциональность провайдера jdk и как я могу это решить?

1 ответ

JDK регистрирует свою собственную версию поставщика безопасности xml, и при инициализации Wss4j XMLSignatureFactory берется из версии JDK, а не из jar-файла Xmlsec. В более новых версиях Wss4j это исправлено в addXMLDSigRI() следующим образом:

    Security.removeProvider("ApacheXMLDSig");
    addJceProvider("ApacheXMLDSig", SantuarioUtil.getSantuarioProvider());

Т.е. сначала удаляет версию провайдера, зарегистрированную JDK, затем регистрирует свою. Это предотвращает проблемы с загрузкой классов, возникающие при использовании JDK от разных поставщиков (например, Azul JDK).

Вы можете отключить регистрацию поставщика Apache Santuario в WSS4J, позвонив:

WSSConfig.setAddJceProviders (ложный);

Посмотреть здесь:

https://svn.apache.org/repos/asf/webservices/wss4j/tags/1_6_10/src/main/java/org/apache/ws/security/WSSConfig.java

Другие вопросы по тегам