Установка расширенного поля метаданных 'signatureAlgorithm'

У меня проблема с получением интеграции Spring SAML для создания правильного файла метаданных для моего IdP. Мне были выданы новые сертификаты SHA256 SSL. Я прошел все шаги по созданию соответствующего хранилища ключей и полностью настроил мой файл конфигурации безопасности Spring. Я буквально нахожусь в 98% случаев, но в сгенерированном файле метаданных отсутствует одна вещь, которую я не могу понять, почему она не устанавливается.

Вот мой конфиг ExtendedMetadata для MetadataGeneratorFilter:

<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
    <bean class="org.springframework.security.saml.metadata.MetadataGenerator">
        <property name="entityId" value="urn:myentityidhere"/>
        <property name="entityBaseURL" value="https://${saml.url}"/>
        <property name="extendedMetadata">
            <bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
                <property name="signMetadata" value="true"/>
                <property name="signingAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
                <property name="alias" value="ceo"/>
                <property name="signingKey" value="${saml.sp.alias}"/>
                <property name="encryptionKey" value="${saml.sp.alias}"/>
            </bean>
        </property>
    </bean>
</constructor-arg>

Когда я запускаю свое приложение и захожу в URI /saml/metadata, чтобы заставить Spring сгенерировать файл метаданных, который мне нужно отправить в мой IdP, алгоритм SHA256 правильно устанавливается на SignatureMethod, но значение алгоритма дочернего тега DigestMethod все еще установлено в SHA1, когда мне нужно, чтобы ТАКЖЕ было установлено значение SHA256 вместе с DigestValue, которое будет значением SHA256, а не значением SHA1.

<ds:SignedInfo>
    <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
    <ds:Reference URI="#urn_myentityidhere">
        <ds:Transforms>
            <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
            <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <ds:DigestValue>xxxxxxx</ds:DigestValue>
    </ds:Reference>
</ds:SignedInfo>

Может кто-нибудь подсказать мне, как / что мне нужно установить, чтобы получить значение алгоритма DigestMethod равным 256? Я подумал, что поскольку он является дочерним по отношению к тегу SignedInfo, он унаследует значение signatureAlgorithm из конфигурации Extendedmetadata, но, увы, это не так.

Любая помощь будет с благодарностью. Спасибо.

РЕШЕНИЕ - На случай, если кому-то все равно

Итак, после целого дня копания я решил просто реализовать это сам. Я расширил класс ExtendedMetadata, добавив поле digestMethodAlgorithm и добавив соответствующий метод получения / установки:

/**
 * Algorithm used for creation of digest method of this entity. At the moment only used for metadata signatures.
 * Only valid for local entities.
 */
private String digestMethodAlgorithm;

/**
 * Returns digest method algorithm value
 * @return String
 */
public String getDigestMethodAlgorithm()
{
    return digestMethodAlgorithm;
}

/**
 * Sets the digest method algorithm to use when signing the SAML messages.
 * This can be used, for example, when a strong algorithm is required (e.g. SHA 256 instead of SHA 128).
 * If this property is null, then the {@link org.opensaml.xml.Configuration} default algorithm will be used instead.
 *
 * Value only applies to local entities.
 *
 * At the moment the value is only used for signatures on metadata.
 *
 * Typical values are:
 * http://www.w3.org/2001/04/xmlenc#sha1
 * http://www.w3.org/2001/04/xmlenc#sha256
 * http://www.w3.org/2001/04/xmlenc#sha384
 * http://www.w3.org/2001/04/xmlenc#sha512
 * http://www.w3.org/2001/04/xmlenc#ripemd160
 *
 * @param digestMethodAlgorithm The new digest method algorithm to use
 * @see org.opensaml.xml.signature.SignatureConstants
 */
public void setDigestMethodAlgorithm(String digestMethodAlgorithm)
{
    this.digestMethodAlgorithm = digestMethodAlgorithm;
}

Затем я изменил свою весеннюю конфигурацию безопасности сверху, чтобы включить это новое свойство bean-компонента, которое будет установлено в моей конфигурации MetadataGenerator:

<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
<constructor-arg>
    <bean class="org.springframework.security.saml.metadata.MetadataGenerator">
        <property name="entityId" value="urn:myentityidhere"/>
        <property name="entityBaseURL" value="https://${saml.url}"/>
        <property name="extendedMetadata">
            <bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
                <property name="signMetadata" value="true"/>
                <property name="signingAlgorithm" value="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
                <property name="digestMethodAlgorithm" value="http://www.w3.org/2001/04/xmlenc#sha256"/>
                <property name="alias" value="ceo"/>
                <property name="signingKey" value="${saml.sp.alias}"/>
                <property name="encryptionKey" value="${saml.sp.alias}"/>
            </bean>
        </property>
    </bean>
</constructor-arg>

Затем мне также пришлось внести два изменения в класс SAMLUtil. В getmetadataAsString в условии if isSignMetadata() я вытащил введенное значение для digestMethodAlgorithm, установленного в приведенной выше конфигурации, а затем дополнительно изменил метод marshallAndSignMessage, чтобы он принимал новый входной параметр, который я в дальнейшем использую, чтобы правильно установить алгоритм DigestMethod,

Внутри SAMLUtil.getMetaDataAsString, строка 572

...
String digestMethodAlgorithm = extendedMetadata.getDigestMethodAlgorithm();
element = SAMLUtil.marshallAndSignMessage(descriptor, credential, signingAlgorithm, digestMethodAlgorithm, keyGenerator);
...

Внутри SAMLUtil.marshallAndSignMessage, сразу после строки 437, я добавил / изменил следующее:

...
BasicSecurityConfiguration secConfig = null;

if (digestMethodAlgorithm != null)
{
    secConfig = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();

    secConfig.setSignatureReferenceDigestMethod(digestMethodAlgorithm);
}

try {
    SecurityHelper.prepareSignatureParams(signature, signingCredential, secConfig, keyInfoGenerator);
} catch (org.opensaml.xml.security.SecurityException e) {
    throw new MessageEncodingException("Error preparing signature for signing", e);
}
...

Я перекомпилировал весь основной пакет Spring SAML с помощью Gradle, spring-security-saml-1.0.0.RELEASE, скопировал новый jar из каталога build/libs в мой проект, развернул webapp, указал мой браузер на /saml/metadata и успешно получен файл метаданных с правильной подписанной частью файла метаданных SHA256.

Я собираюсь посмотреть, что я могу сделать, чтобы передать это в репозиторий git для этого проекта, потому что я не хочу терять эту способность, так как проект делает будущие выпуски. Никогда раньше не участвовал в таком проекте с открытым исходным кодом.

<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#urn_myentityidhere">
    <ds:Transforms>
        <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
        <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
    </ds:Transforms>
    <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
    <ds:DigestValue>xxxxxx</ds:DigestValue>
</ds:Reference>

3 ответа

Ситуация изменилась после ответа @VladimírSchäfer; у нас он не работал с AD FS 2.0 и SHA-256. Нам пришлось добавить дополнительные настройки, чтобы заставить его работать (см. Код ниже).

Проблема, по-видимому, заключается в библиотеке xmltooling OpenSAML, особенно в org.opensaml.xml.security.BasicSecurityConfiguration.getSignatureAlgorithmURI(Credential) метод - вместо того, чтобы просто использовать алгоритм подписи сертификата (в нашем случае, SHA256withRSA), он получает ключ сертификата, затем просматривает алгоритм этого ключа и использует карту зарегистрированных URI для поиска URI подписи. Если бы у них была просто карта алгоритмов подписи JCA к URI вместо ключевых алгоритмов к URI, все было бы хорошо.

Обходной путь должен зарегистрировать правильный алгоритм подписи URI с BasicSecurityConfiguration во время весенней проводки, перезаписывая (нежелательный) URI http://www.w3.org/2000/09/xmldsig#rsa-sha1 это уже присутствует с http://www.w3.org/2001/04/xmldsig-more#rsa-sha256,

Мы также должны были удалить setSignatureReferenceDigestMethod() вызов или импорт метаданных в AD FS не удастся.

import org.opensaml.Configuration;
import org.opensaml.xml.security.BasicSecurityConfiguration;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.security.saml.SAMLBootstrap;

public class CustomSamlBootstrap extends SAMLBootstrap {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
super.postProcessBeanFactory(beanFactory); BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration(); config.registerSignatureAlgorithmURI("RSA", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); } }

Вы можете настроить метод дайджеста для вычисления цифровых подписей, выполнив следующий вызов во время инициализации Spring SAML:

// Use SHA-256 signatures for RSA keys
BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();
config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256);

Например, расширить по умолчанию org.springframework.security.saml.SAMLBootstrap и добавьте код в переопределенный метод postProcessBeanFactory после вызова super:

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    super.postProcessBeanFactory(beanFactory);
    BasicSecurityConfiguration config = (BasicSecurityConfiguration) Configuration.getGlobalSecurityConfiguration();
    config.setSignatureReferenceDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256);
}

Это изменение влияет как на подписи в сгенерированных метаданных, так и на подписи в сгенерированных сообщениях SAML.

После внесения изменений в SAMLBootstrap для конфигурации глобальной безопасности я столкнулся со следующим исключением:

org.apache.xml.security.signature.XMLSignatureException: запрошенный алгоритм SHA256 с RSA не существует. Исходное сообщение было: SHA256withRSA MessageDigest недоступно в org.apache.xml.security.algorithms.MessageDigestAlgorithm.getDigestInstance(неизвестный источник) в org.apache.xml.security.algorithms.MessageDigestAlgorithm.getInstance(неизвестный источник) или в неизвестном источнике).security.signature.Reference. (Неизвестный источник) в org.apache.xml.security.signature.Manifest.addDocument (Неизвестный источник) в org.apache.xml.security.signature.XMLSignature.addDocument(Неизвестный источник)

После дальнейшего расследования выяснилось, что Apache XML Security xmlsec-1.4.3.jar не поддерживает базовый SHA256withRSA алгоритм.

Разрешение: использовать xmlsec-2.0.2.jar со https://mvnrepository.com/artifact/org.apache.santuario/xmlsec/2.0.2

Этот новый кувшин решил проблему.

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