Cifrado de Mensajes
A veces, los mensajes requieren seguridad más allá de la seguridad a nivel de transporte, como SSL. Para estos casos, los conectores pueden configurarse para cifrar o descifrar mensajes al enviar o recibir mensajes, respectivamente. Esto sitúa la seguridad a nivel de aplicación además de cualquier mecanismo de seguridad a nivel de transporte que pueda estar en su lugar.
Interfaz Cripto
Para añadir cifrado de mensajes, se debe proporcionar una implementación de la interfaz Crypto al construir el conector. Si no se proporciona ninguna implementación de Crypto, entonces esta etapa se omite y el transport message se recibe tal cual.
La interfaz es simple y consiste en dos métodos, encriptar y desencriptar.
public interface Crypto {
/**
* @param plaintext message to send
* @param cryptoProperties properties to define encryption
* @return encrypted message
*/
String encrypt(String plaintext, CryptoProperties cryptoProperties);
/**
* @param payload encrypted message received
* @param cryptoProperties properties to define encryption
* @return decrypted message
*/
String decrypt(String payload, CryptoProperties cryptoProperties);
}
Configuración de Crypto
La biblioteca de conectores proporciona dos implementaciones de la interfaz Crypto. Estos son:
NoopCrypto
Esta es una clase de paso de texto plano que registrará los datos a nivel de DEBUG. Generalmente se utiliza para pruebas.
NoopCrypto no requiere configuración.
Crypto Simétrico
Requiere una clave para la encriptación y desencriptación que luego es utilizada por los métodos de encriptación. Se asume que la contraseña clave es la misma que la contraseña del almacén de claves.
La clase SymmetricCrypto requiere cierta configuración para funcionar. Las siguientes propiedades deben ser proporcionadas al construir una instancia de SymmetricCrypto.
| Clave | Descripción |
|---|---|
keystorePath |
La ruta absoluta al almacén de claves |
tipo De Almacén De Claves |
Tipo de almacén de claves como PKCS12 |
contraseña Del Almacén De Claves |
Contraseña utilizada para el almacén de claves |
transformación |
Transformación de cifrado a utilizar, p. ej. "AES/CBC/NoPadding" Consulte los Javadocs) |
Utilizando el constructor SymmetricCrypto, podemos instanciar una instancia.
SymmetricCrypto symmetricCrypto = SymmetricCrypto.builder()
.withKeystorePath(keystorePath)
.withKeystoreType("PKCS12")
.withKeystorePassword("keystore-password")
.withTransformation("AES/CBC/PKCS5Padding")
.build();
Uso
Ambos envían y receive connector s tiene un campo de criptografía, que permite al desarrollador proporcionar una implementación de Crypto, o no, si no es necesario.
Los CryptoHeaders son necesarios para garantizar que se pase una clave y que la encriptación se pueda activar o desactivar a nivel de mensaje.
Send Connector Ejemplo
Crypto crypto = getSymmetricCrypto(); (1)
SendConnector
.<ExampleType, ExampleType>builder(connectorName)
.withActorSystem(actorSystem)
.withConnectorTransport(connectorTransport)
.withSendTransportMessageConverter(messageConverter)
.withCorrelationIdExtractor(correlationIdExtractor)
.withCorrelationService(correlationService)
.withCrypto(crypto) (2)
.build();
| 1 | Obtiene una implementación de Crypto (simbólica en este ejemplo) |
| 2 | Proporciona la implementación de Crypto. |
Receive Connector Ejemplo
Crypto crypto = new NoopCrypto(); (1)
ReceiveConnector
.<ExampleType>builder(connectorName)
.withActorSystem(actorSystem)
.withConnectorTransport(connectorTransport)
.withReceiveTransportMessageConverter(messageConverter)
.withReceiveHandler(receiver)
.withMessageLogger(messageLogger)
.withProcessingContextExtractor(processingContextExtractor)
.withCrypto(crypto) (2)
.build();
| 1 | Instancia la implementación de Crypto (sin operación en este ejemplo) |
| 2 | Proporciona la implementación de Crypto. |
Encabezados de Mensajes Cripto
Al utilizar Crypto con conectores, los mensajes deben enviarse con los siguientes encabezados. Si no se proporcionan, se utilizarán los valores predeterminados.
| Clave | Descripción | Predeterminado |
|---|---|---|
keyAlias |
El alias clave que se está utilizando |
empty string |
esquemaDeCifrado |
El esquema de cifrado en uso.
Puede configurarse a |
|
El enum CryptoHeader está incluido en la API.
public enum CryptoHeaders {
KEY_ID("keyAlias"),
SCHEME("encryptionScheme");
private final String headerName;
CryptoHeaders(String headerName) {
this.headerName = headerName;
}
}
Juntando todo esto, podemos crear un método para instanciar los encabezados de mensaje requeridos.
private MessageHeaders messageHeaders() {
return new MessageHeaders()
.putHeader(CryptoHeaders.KEY_ID.getHeaderName(), "GWPAY01")
.putHeader(CryptoHeaders.SCHEME.getHeaderName(), "AES")
.putHeader("msgKey", "value1");
}
Luego colóquelos en el transport message, junto con la carga útil en el SendTransportMessageConverter interfaz funcional que puede ser declarada utilizando una lambda.
private SendTransportMessageConverter<ExampleType> sendTransportMessageConverter() {
return payload -> new TransportMessage(
messageHeaders(), (1)
serialisePayload(payload)
);
}
El SendTransportMessageConverter puede ser utilizado al construir un sending connector y todos los mensajes enviados a través de él tendrán los CryptoHeaders configurados. Este simple ejemplo demuestra cómo establecer los encabezados de forma estática; sin embargo, pueden establecerse de manera dinámica en función de la carga útil si esto es necesario con un esfuerzo adicional mínimo.