Неверная цепочка сертификатов при попытке зарегистрировать устройство (DPS)

Вопрос или проблема

Я уже несколько дней пытаюсь решить проблему и не могу найти решение для следующей ошибки, которая говорит о том, что цепочка сертификатов недействительна. У меня есть родительский сертификат, полученный из хранилища, с его помощью я создаю и подписываю дочерний сертификат, а затем пытаюсь зарегистрировать устройство с помощью клиента поставки устройства. Когда устройство пытается зарегистрироваться, возникает следующая ошибка. Я точно не знаю, где я ошибаюсь, так как шаги по созданию и подписанию дочернего сертификата выглядят абсолютно правильно.

Причина: java.security.KeyStoreException: Цепочка сертификатов недействительна
    в java.base/sun.security.pkcs12.PKCS12KeyStore.setKeyEntry(PKCS12KeyStore.java:650)
    в java.base/sun.security.pkcs12.PKCS12KeyStore.engineSetKeyEntry(PKCS12KeyStore.java:593)
    в java.base/sun.security.util.KeyStoreDelegator.engineSetKeyEntry(KeyStoreDelegator.java:114)
    в java.base/java.security.KeyStore.setKeyEntry(KeyStore.java:1192)
    в com.microsoft.azure.sdk.iot.provisioning.security.SecurityProviderX509.generateSSLContext(SecurityProviderX509.java:73)
    в com.microsoft.azure.sdk.iot.provisioning.security.SecurityProviderX509.getSSLContext(SecurityProviderX509.java:40)

Вот пример фрагмента кода

generateSelfSignedX509Certificate используется для подписания и генерации дочернего сертификата. Параметр типа KeyPair signingCertKeyPair представляет собой комбинацию родительского закрытого ключа и открытого ключа для дочернего сертификата, созданного как новая пара ключей. Таким образом, signingCertKeyPair = родительскийЗакрытыйКлюч + дочернийОткрытыйКлюч. Родительский закрытый ключ используется для подписания нового сгенерированного дочернего x509 сертификата.

var childCertificate = generateSelfSignedX509Certificate(signingCertKeyPair, certificateRequest.getDeviceId,
        parentCertPolicy.getProperties().getNotBefore(), parentCertPolicy.getProperties().getExpiresOn());
Collection<X509Certificate> signerCertificates = new LinkedList<>();
byte[] certificateContent = parentCertPolicy.getCer();
String parentCertificate = Base64.getEncoder().encodeToString(certificateContent);
signerCertificates.add(parsingOfPublicKeyCertificate(parentCertificate));
var securityProvider = JLGSecurityProviderX509.newBuilder()
        .withChildCert(childCertificate)
        .withSignerCertificates(signerCertificates)
        .withSignerCommonName(certificateRequest.deviceId)
        .withPrivateKey(signingCertKeyPair.getPrivate())
        .build();
var provisioningDeviceClient = ProvisioningDeviceClient.create(dpsCertConfig.globalEndpoint(), dpsCertConfig.idScope(), PROTOCOL, securityProvider);
provisioningDeviceClient.registerDeviceSync();//Эта строка вызывает исключение недействительного сертификата
provisioningDeviceClient.close();

Ответ или решение

Ответ на ваш вопрос о проблеме с недействительной цепочкой сертификатов при попытке зарегистрировать устройство через Azure Device Provisioning Service (DPS) требует внимательного рассмотрения каждого шага. Ошибка "Certificate chain is not valid" часто связана с неправильной конфигурацией сертификатов или их принадлежностью. Давайте разберёмся в возможных причинах и предложим пути их решения.

Возможные причины ошибки

  1. Проблемы с родительским сертификатом:

    • Убедитесь, что родительский сертификат загружен правильно и действителен. Он должен быть подписан доверенным корневым сертификатом, который также должен быть доступен.
  2. Неверная цепочка сертификатов:

    • При создании дочернего сертификата важно, чтобы он правильно ссылался на родительский сертификат. Убедитесь, что дочерний сертификат действительно подписан приватным ключом родительского сертификата.
  3. Проблемы с форматом сертификатов:

    • Убедитесь, что сертификаты корректно сериализованы и имеют правильный формат. Например, базовое кодирование (Base64) и DER-формат могут иметь разные обертки.
  4. Некорректные атрибуты сертификатов:

    • Проверьте, что атрибуты создаваемого сертификата, такие как срок действия, соответствуют политике и ожиданиям системы DPS.
  5. Неправильный порядок сертификатов:

    • Убедитесь, что вы добавляете сертифицированный родительский сертификат в правильном порядке. Цепочка сертификатов должна начинаться с дочернего сертификата и двигаться к родителю, а затем к корню.

Рекомендации по исправлению ошибки

  1. Проверка родительского сертификата:

    • Убедитесь, что родительский сертификат действителен и совпадает с приватным ключом для подписания дочернего сертификата. Вы можете использовать инструменты, такие как OpenSSL, для проверки сертификата.
  2. Подготовка иериархии сертификатов:

    • Убедитесь, что все сертификаты (дочерний, родительский и корневой) правильно настроены и связаны друг с другом. Если вы используете цепочку, убедитесь, что все нужны промежуточные сертификаты также добавлены.
  3. Проверка реализации кода:

    • Убедитесь, что вызовы в вашем коде правильные и вы правильно создаете самозаверяющий сертификат. Например, убедитесь, что generateSelfSignedX509Certificate() возвращает корректный объект типа X509Certificate.
  4. Использование отладочных средств:

    • Используйте средства отладки и журналирования для отслеживания, в какой момент возникает ошибка, и изучите подробные сообщения об ошибках, если система предоставит дополнительные данные.
  5. Тестирование с минимальной конфигурацией:

    • Попробуйте упростить код до самого простого вида, чтобы изолировать проблему. Например, создайте временный сертификат с фиксированными параметрами и протестируйте его регистрацию.

Пример исправленного кода

Проверьте и замените фрагмент кода следующим образом:

// Генерация дочернего сертификата
X509Certificate childCertificate = generateSelfSignedX509Certificate(signingCertKeyPair, /* другие параметры */);

// Проверка формата родительского сертификата
if (parentCertPolicy.getCer() != null) {
    String parentCertificateEncoded = Base64.getEncoder().encodeToString(parentCertPolicy.getCer());
    X509Certificate parentCertificate = parsingOfPublicKeyCertificate(parentCertificateEncoded);

    // Удостовериться, что сертификат правильно добавлен
    Collection<X509Certificate> signerCertificates = new LinkedList<>();
    signerCertificates.add(parentCertificate);

    // Создание провайдера безопасности
    JLGSecurityProviderX509 securityProvider = JLGSecurityProviderX509.newBuilder()
            .withChildCert(childCertificate)
            .withSignerCertificates(signerCertificates)
            .withSignerCommonName(certificateRequest.getDeviceId())
            .withPrivateKey(signingCertKeyPair.getPrivate())
            .build();

    // Регистрация устройства
    try (ProvisioningDeviceClient provisioningDeviceClient = ProvisioningDeviceClient.create(dpsCertConfig.globalEndpoint(), dpsCertConfig.idScope(), PROTOCOL, securityProvider)) {
        provisioningDeviceClient.registerDeviceSync();
    } catch (Exception e) {
        e.printStackTrace(); // Логирование исключения для отладки
    }
}

Заключение

Проблема с недействительной цепочкой сертификатов часто кроется в ошибках настройки сертификатов, поэтому внимательно проверяйте каждый шаг процесса. Убедитесь, что все сертификаты верны и находятся в корректной последовательности. Если проблема сохраняется, попробуйте обратиться в поддержку Azure с детальным описанием ваших шагов и кодом для получения более специфичных советов.

Оцените материал
Добавить комментарий

Капча загружается...