Show / Hide Table of Contents

    Encryption

    The end-to-end message encryption in Silverback is handled transparently in the producer and consumer and works independently from the used serializer or other features like chunking.

    The messages are transparently encrypted and decrypted.

    Symmetric encryption

    Enabling the end-to-end encryption using a symmetric algorithm just require an extra configuration in the endpoint.

    • Fluent
    • Legacy
    public class MyEndpointsConfigurator : IEndpointsConfigurator
    {
        public void Configure(IEndpointsConfigurationBuilder builder) =>
            builder
                .AddKafkaEndpoints(endpoints => endpoints
                    .Configure(config => 
                        {
                            config.BootstrapServers = "PLAINTEXT://kafka:9092"; 
                        })
                    .AddOutbound<InventoryEvent>(endpoint => endpoint
                        .ProduceTo("inventory-events")
                        .EncryptUsingAes(encryptionKey))
                    .AddInbound(endpoint => endpoint
                        .ConsumeFrom("order-events")
                        .Configure(config => 
                            {
                                config.GroupId = "my-consumer";
                            })
                        .DecryptUsingAes(encryptionKey)));
    }
    
    public class MyEndpointsConfigurator : IEndpointsConfigurator
    {
        public void Configure(IEndpointsConfigurationBuilder builder) =>
            builder
                .AddOutbound<InventoryEvent>(
                    new KafkaProducerEndpoint("inventory-events")
                    {
                        Configuration = new KafkaProducerConfig
                        {
                            BootstrapServers = "PLAINTEXT://kafka:9092"
                        },
                        Encryption = new SymmetricEncryptionSettings
                        {
                            AlgorithmName = "AES",
                            Key = encryptionKey
                        } 
                    })
                .AddInbound(
                    new KafkaConsumerEndpoint("order-events")
                    {
                        Configuration = new KafkaConsumerConfig
                        {
                            BootstrapServers = "PLAINTEXT://kafka:9092",
                            GroupId = "my-consumer"
                        },
                        Encryption = new SymmetricEncryptionSettings
                        {
                            AlgorithmName = "AES",
                            Key = encryptionKey
                        } 
                    });
    }
    

    The SymmetricEncryptionSettings class encapsulates all common settings of a symmetric algorithm (block size, initialization vector, ...).

    The AlgorithmName is used to load the algorithm implementation using the SymmetricAlgorithm.Create(string) method. Refer to the SymmetricAlgorithm class documentation to see which implementations are available in .net core are. Silverback uses Aes by default.

    Random initialization vector

    If no static initialization vector is provided, a random one is automatically generated per each message and prepended to the actual encrypted message. The consumer will automatically extract and use it.

    It is recommended to stick to this default behavior, for increased security.

    Ket rotation

    You can smoothly rotate the key being used to encrypt the messages.

    In the outbound endpoint you can specify the current key identifier to be submitted as header, while in the inbound endpoint a custom function can be used to provide the correct key, depending on the value in the header. This simple mechanism allows to consume messages that were encrypted using different keys, enabling key rotation and supporting a rolling update of the producers.

    • Fluent
    • Legacy
    public class MyEndpointsConfigurator : IEndpointsConfigurator
    {
        public void Configure(IEndpointsConfigurationBuilder builder) =>
            builder
                .AddKafkaEndpoints(endpoints => endpoints
                    .Configure(config => 
                        {
                            config.BootstrapServers = "PLAINTEXT://kafka:9092"; 
                        })
                    .AddOutbound<InventoryEvent>(endpoint => endpoint
                        .ProduceTo("inventory-events")
                        .EncryptUsingAes(encryptionKey, "key1"))
                    .AddInbound(endpoint => endpoint
                        .ConsumeFrom("order-events")
                        .Configure(config => 
                            {
                                config.GroupId = "my-consumer";
                            })
                        .DecryptUsingAes(keyIdentifier => 
                            {
                                switch (keyIdentifier)
                                {
                                    case "key1":
                                        return encryptionKey1;
                                    default:
                                        return encryptionKey2;
                                }
                            })));
    }
    
    public class MyEndpointsConfigurator : IEndpointsConfigurator
    {
        public void Configure(IEndpointsConfigurationBuilder builder) =>
            builder
                .AddOutbound<InventoryEvent>(
                    new KafkaProducerEndpoint("inventory-events")
                    {
                        Configuration = new KafkaProducerConfig
                        {
                            BootstrapServers = "PLAINTEXT://kafka:9092"
                        },
                        Encryption = new SymmetricEncryptionSettings
                        {
                            AlgorithmName = "AES",
                            KeyProvider = encryptionKey,
                            KeyIdentifier = "key1"
                        } 
                    })
                .AddInbound(
                    new KafkaConsumerEndpoint("order-events")
                    {
                        Configuration = new KafkaConsumerConfig
                        {
                            BootstrapServers = "PLAINTEXT://kafka:9092",
                            GroupId = "my-consumer"
                        },
                        Encryption = new SymmetricEncryptionSettings
                        {
                            AlgorithmName = "AES",
                            KeyProvider = keyIdentifier => 
                            {
                                switch (keyIdentifier)
                                {
                                    case "key1":
                                        return encryptionKey1;
                                    default:
                                        return encryptionKey2;
                                }
                            }
                        } 
                    });
    }
    
    • Improve this doc
    GitHub E-Mail
    ↑ Back to top © 2020 Sergio Aquilini