Возникла ошибка – Не удалось получить signerInfo для signer.getSubjectX500Principal(), при вызове функции scepclient.enrol.

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

Я разрабатываю прокси-сервер SCEP как приложение Spring Boot, предназначенное для перенаправления запросов SCEP из Java-приложения на сервер SCEP. Прокси обрабатывает GET-запросы, и я сталкиваюсь с проблемой, когда пытаюсь декодировать pkiMessage с помощью jscep. В частности, я вижу, что signerInfo равен null во время операции scepClient.enrol. Во время PKIOperation прокси напрямую перенаправляет GET-запрос на сервер SCEP и возвращает байтовый массив ответа в Java-приложение.
Ниже приведен фрагмент кода Spring Boot приложения-

if ("GetCACert".equalsIgnoreCase(operation)) {
    logger.info("Обработка операции GetCACert для сообщения: {}", message);

    CertStore caCertStore = scepClient.getCaCertificate(message);
    Collection<? extends Certificate> caCertificates = caCertStore.getCertificates(null);

    if (!caCertificates.isEmpty()) {
        Certificate caCert = caCertificates.iterator().next();

        if (caCert instanceof X509Certificate) {
            X509Certificate x509Cert = (X509Certificate) caCert;
            logCaCertificateDetails(x509Cert);

            // Кодирование сертификата в Base64 и установка заголовков
            String base64EncodedCert = new String(Base64.encode(x509Cert.getEncoded()));
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.asMediaType(MimeType.valueOf("application/x-x509-ca-cert")));

            return ResponseEntity.ok().headers(headers).body(x509Cert.getEncoded());
        } else {
            throw new CertStoreException("Сертификат не является X509Certificate.");
        }
    } else {
        throw new CertStoreException("Сертификаты не найдены в хранилище CA CertStore.");
    }
} else if ("PKIOperation".equalsIgnoreCase(operation)) {
    logger.info("Обработка PKI операции для сообщения: {}", message);

    byte[] responseBytes = forwardGetRequest(operation, message);
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.asMediaType(MimeType.valueOf("application/x-pki-message")));

    return ResponseEntity.ok().headers(headers).body(responseBytes);
}

Во время PKIOperation я пытаюсь перенаправить запрос и получить байты ответа от сервера SCEP, но при обработке с помощью jscep я сталкиваюсь с null signerInfo.

Соответствующий раздел кода в jscep, где я сталкиваюсь с ошибкой, выглядит следующим образом:

public PkiMessage<?> decode(final CMSSignedData pkiMessage) throws MessageDecodingException {
    LOGGER.debug("Декодирование pkiMessage");
    validate(pkiMessage);

    CMSProcessable signedContent = pkiMessage.getSignedContent();
    SignerInformationStore signerStore = pkiMessage.getSignerInfos();
    SignerInformation signerInfo = signerStore.get(new JcaSignerId(signer));

    if (signerInfo == null) {
        throw new MessageDecodingException("Не удалось найти signerInfo для " + signer.getSubjectX500Principal());
    }
}

Что я пробовал-
Проверил, что объект CMSSignedData заполнен.
Подтвердил, что сертификат CA корректно извлекается в GetCACert.
Проверил, что сервер SCEP доступен и отвечает.
Без использования прокси SCEP Java-приложение может корректно получить сертификат с сервера без каких-либо ошибок.

Может кто-нибудь указать, где я ошибаюсь, и подсказать, что я могу сделать для отладки вышеизложенного?

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

Ошибка "Could not find signerInfo for signer.getSubjectX500Principal()" при вызове метода scepClient.enrol указывает на то, что информация о подписанте отсутствует в декодированном PKI-сообщении. Это может происходить по нескольким причинам, и в этой статье мы детально разберем возможные источники проблемы и шаги для их устранения.

Разбор проблемы

  1. Отсутствие signerInfo:
    Ошибка возникает в коде метода decode(), когда signerInfo возвращает null. Это указывает на то, что система не может найти информацию о подписанте, что может быть связано с различными факторами в процессе обработки данных.

  2. Проблемы с PKI-сообщением:
    Убедитесь, что сообщение PKI, передаваемое от вашего SCEP-прокси к серверу, корректно сформировано и содержит все необходимые поля. А именно:

    • Подписанный контент
    • Информация о подписанте
  3. Не корректная маршрутизация данных:
    Проверьте, корректно ли вы пересылаете данные между клиентом и сервером. Возможно, некоторые поля теряются или искажаются в процессе передачи.

Рекомендации по отладке

1. Логирование

Добавьте дополнительные логгирования на всех этапах обработки запроса и ответа. Это поможет увидеть:

  • Какая информация передается в запросе и получаемом ответе
  • Корректно ли декодируется CMSSignedData
  • Есть ли другие сообщения об ошибках в логах, которые могли бы объяснить проблему

2. Проверка содержимого responseBytes

Прежде чем вызывать scepClient.enrol, убедитесь, что responseBytes, полученные от SCEP-сервера, действительно содержат корректное PKI-сообщение. Для этого:

  • Распечатывайте размер массива байтов
  • Проверьте, что содержимое соответствует стандарту PKCS#7/CMS

3. Валидация PKI-сообщения

В методе decode() добавьте дополнительную валидацию, чтобы убедиться, что переданный CMSSignedData объект не просто заполнен, но и корректно сформирован:

if (pkiMessage.getSignerInfos().getSigners().isEmpty()) {
    throw new MessageDecodingException("No signer information present in the PKI message.");
}

4. Сравнение с работающим кодом

Так как указано, что при прямом обращении к SCEP-серверу все работает корректно, сравните что именно отличается в запросах и ответах:

  • Используйте инструменты типа Wireshark или Postman, чтобы захватить и проанализировать HTTP-трафик.
  • Сравните заголовки и тела запросов.

Заключение

Ошибка, с которой вы столкнулись, указывает на потенциальные проблемы в процессе передачи или обработке данных в рамках вашего SCEP-прокси. Применяя описанные шаги для отладки и улучшая логирование, вы сможете pinpoint проблему и устранить ее.

Если все вышеперечисленные шаги не приведут к успеху, возможно, потребуется более глубокое изучение используемого вами API jscep и его взаимодействия с SCEP-сервером.

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

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