Security - xylamic/lightrail-pubsub-integration-framework GitHub Wiki

Security Type

The security used in Lightrail is symmetric AES 256-bit encryption. This is a high strength and high performance method for strong encryption. Any Terminal can be bound to a particular Security Key. A Security Key defines the mechanism for encryption and decryption of messages.

Since a particular Security Key can be bound to a Terminal, or a Terminal can be independent of security as in the "Instances" explanation, a single application can transfer messages with multiple securities and security types at the same time.

Implementing Security

A Security Key must first be registered before it can be attached to a Terminal. Once registered, a Terminal can then be registered with the specified security key.

Example C++

// register a key using an ASCII string
const char* key = "ThisIsMyKey!";
const ISecurityKey* seckey = Lightrail::NewAES256SecurityKey(L"SecKey1", key, strlen(key));
client->RegisterSecurityKey(seckey);

// register the Terminal and specify the key name that was registered
const ITerminal* terminal = Lightrail::NewTerminal(L"PubTerminal", L"PubDesc",
     L"[Global>Company>Region>Domain>App>Instance>Publish]", L"SecKey1");
client->RegisterTerminal(Standpoint::PUBLISHER, terminal);

Example C#

// register a key using a string and getting a UTF-8 byte array from it
client.RegisterSecurityKey("SecKey1", System.Text.Encoding.UTF8.GetBytes("ThisIsMyKey!"));

// register the Terminal and specify the key name that was registered
client.RegisterTerminal(TerminalStandpoint.Publisher, "PubTerminal", "PubDesc", 
    "[Global>Company>Region>Domain>App>Instance>Publish]", "SecKey1");

This examples uses a string as the "key" for encryption. This can be any binary data of any length. Since it is 256-bit encryption being used, the optimal key length is 32 bytes.

Thoughts on Security

With this method of security, the data in the message is very secure. The main consideration for securing your data is the security of your key itself. If you are sending and receiving very sensitive data, take caution as to how you store or generate your key as this is the most likely place your data will be compromised.

Security and Parsing Errors

If a sender's key does not match a receiver's, if there are multiple Terminals with conflicting security information receiving the same message, or another issue with receiving a message, the message cannot be delivered to you. The question then becomes, how do you know if you were supposed to receive a message, but you did not because it encountered an error before it could be delivered? The answer is the Parse Error event receiver. The event callback can be set up similar to a Request Received or Publish Received. This event will deliver information to you explaining what the problem was, where it originated from, and what Terminal it was arriving on.

Example C++

// set up the callback using your class instance
client->OnDeliveryParseError.SetCallback(new XEventCallback<YourClassName, 
     const IDeliveryParseError&>(this, &YourClassName::DeliveryParseError));

// set up the method for receipt
void DeliveryParseError(const IDeliveryParseError& error)
{
     const std::exception& stdex = error.Message();
}

Example C#

// set up the callback
client.OnParseErrorReceived += new ParseErrorReceived(client_OnParseErrorReceived);

// set up the method for receipt
void client_OnParseErrorReceived(DeliveryParseError error)
{
     string errorMessage = error.Message();
}

This information can be very beneficial not only for security purposes, but for general diagnosis of infrastructure issues.