Certificate-signature-interceptor#
Interceptor предназначен для подписи сообщения с помощью X509 сертификата для контроля целостности сообщений.
Принцип работы#
Interceptor может работать в двух режимах:
public-key;certificate-serial.
Public-key#
Producer-interceptor получает приватный ключ и сертификат.
Producer-interceptor подписывает value сообщения и добавляет подпись (signature), алгоритм подписи (algorithm) и публичный ключ (public key) сертификата в заголовки сообщения.
Consumer-interceptor проверяет подпись сообщения (signature), используя алгоритм (algorithm) и публичный ключ (public key) из заголовков сообщения.
Certificate-serial#
Producer-interceptor получает приватный ключ и сертификат.
Producer-interceptor подписывает value сообщения и добавляет подпись (signature), алгоритм подписи (algorithm) и серийный номер (certificate serial) сертификата в заголовки сообщения.
Consumer-interceptor получает публичный ключ сертификата по его серийному номеру, указанному в заголовке сообщения из локального хранилища (JKS или текстового файла).
Consumer-interceptor проверяет подпись сообщения (signature), используя алгоритм (algorithm) и полученный публичный ключ.
Важно! При использовании certificate-signature-interceptor возможно значительное падение производительности в связи с высокой математической сложностью алгоритма подписи сертификата х509. Для установления конкретных показателей для определенного взаимодействия необходимо проведение НТ.
Конфигурация#
Для конфигурирования interceptor возможно сформировать файл *.properties с необходимыми параметрами.
Certificate-signature-interceptor поддерживает следующие параметры:
Настройка |
Назначение |
Дефолтное значение |
Комментарии |
|---|---|---|---|
signature.certificate.mode |
Режим работы interceptor |
- |
Обязательная |
signature.certificate.algorithm |
Алгоритм подписи |
SHA256withRSA |
Обязательная |
signature.certificate.key.alias |
Алиас приватного ключа |
- |
Обязательная |
signature.certificate.cert.alias |
Алиас сертификата |
- |
Обязательная |
signature.certificate.keystore.type |
Хранилище сертификатов(jks, pem, vault) |
- |
Обязательная |
signature.certificate.truststore.type |
Хранилище сертификатов(jks, pem, vault) |
- |
Обязательная |
signature.certificate.algorithm.attribute |
Имя загловка с используемым алгоритмом подписи |
algorithm |
Опциональная |
signature.certificate.public.key.attribute |
Имя заголовка с публичным ключом для проверки подписи |
public.key |
Опциональная |
signature.certificate.serial.attribute |
Имя заголовка с используемым серийным номером сертификата |
certificate.serial |
Опциональная |
signature.certificate.allowed.serial |
Проверка серийного номера сертификата в списке разрешенных серийных номеров |
false |
Опциональная |
signature.certificate.allowed.serial.file |
Расположение списка разрешенных серийных номеров сертификата |
- |
Опциональная |
signature.certificate.ssl.provider |
ssl-провайдер |
- |
Настройки SSL |
signature.certificate.ssl.keystore.location |
Хранилище сертификата и приватного ключа для сервера |
- |
Настройки SSL |
signature.certificate.ssl.keystore.type |
Тип хранилища сертификатов |
- |
Настройки SSL |
signature.certificate.ssl.keystore.password |
Пароль от хранилища сертификатов |
- |
Настройки SSL |
signature.certificate.ssl.key.password |
Пароль от ключа |
- |
Настройки SSL |
signature.certificate.ssl.truststore.location |
Путь до хранилища доверенных сертификатов |
- |
Настройки SSL |
signature.certificate.ssl.truststore.password |
Пароль к хранилищу доверенных сертификатов |
- |
Настройки SSL |
В случае использования хранилища сертификатов vault, в параметрах необходимо указать параметры подключения, указанные в ssl-context-builder.
Поведение при ошибках#
В случае, если сообщение не прошло проверку подписи при получении (на стороне consumer-interceptor), поведение настраивается с помощью параметра failMode:
filter: сообщение об ошибке будет залогировано в error, клиент не получит невалидное сообщение;addErrorHeader: сообщение, полученное consumer, будет иметь заголовокsignature.errorс ошибкой проверки подписи.
Примеры подключения interceptor к core-клиенту#
Подключение исходящего certificate-signature-interceptor на producer#
CertificateSignatureInterceptor outgoingInterceptor = CertificateSignatureInterceptor.newBuilder()
.setSignatureMode("public-key")
.setAlgorithm("SHA256WithRSA")
.setKeyStoreType("jks")
.setSSLKeystoreLocation("path/to/cert/keystore.jks")
.setSSLKeystorePassword("password")
.setSSLKeyPassword("password")
.build();
ServerLocator locator = ActiveMQClient.createServerLocator("tcp://host::port?TranspotConfiguration");
locator.addOutgoingInterceptor(outgoingInterceptor);
ClientSessionFactory factory = locator.createClientSessionFactory();
ClientSession session = factory.createSession();
// addressName=example, queueName=example
ClientProducer producer = session.createProducer("example");
ClientMessage message = session.createMessage(Message.TEXT_TYPE, config.durable);
TextMessageUtil.writeBodyText( ((CoreMessage) clientMessage).getBodyBuffer, "Hello");
producer.send(message);
Подключение входящего certificate-signature-interceptor на consumer#
CertificateSignatureInterceptor incomingInterceptor = CertificateSignatureInterceptor.newBuilder()
.setSignatureMode("public-key")
.setAlgorithm("SHA256WithRSA")
.setKeyStoreType("jks")
.setSSLKeystoreLocation("path/to/cert/keystore.jks")
.setSSLKeystorePassword("password")
.setSSLKeyPassword("password")
.build();
ServerLocator locator = ActiveMQClient.createServerLocator("tcp://host::port?TranspotConfiguration");
locator.addIncomingInterceptor(incomingInterceptor);
ClientSessionFactory factory = locator.createClientSessionFactory();
ClientSession session = factory.createSession();
// addressName=example, queueName=example
ClientConsumer consumer = session.createConsumer("example");
session.start();
ClientMessage msgReceived = consumer.receive();