/// <summary> /// Enqueue message thread safe /// </summary> /// <param name="message"></param> internal void AddMessageToQueue(SinricMessage message) { var payloadJson = JsonConvert.SerializeObject(message.Payload); message.RawPayload = new JRaw(payloadJson); // compute the signature using our secret key so that the service can verify authenticity message.Signature.Hmac = HmacSignature.Signature(payloadJson, SecretKey); OutgoingMessages.Enqueue(message); Debug.Print("Queued websocket message for sending"); }
internal static bool ValidateMessageSignature(SinricMessage message, string secretKey) { var payloadString = message.RawPayload?.Value as string; if (!string.IsNullOrEmpty(payloadString)) { // if the message contains a payload then we need to validate its signature // todo validate timestamp of message, must be within X seconds of local clock, and must be > than the last message time received to protect against replay attacks // compute a local signature from the raw payload using our secret key: var signature = HmacSignature.Signature(payloadString, secretKey); // compare the locally computed signature with the one supplied in the message: return(signature == message.Signature.Hmac); } return(true); }
private void WebSocketOnMessageReceived(object sender, MessageReceivedEventArgs e) { Debug.Print("Websocket message received:\n" + e.Message + "\n"); try { var message = JsonConvert.DeserializeObject <SinricMessage>(e.Message); if (!HmacSignature.ValidateMessageSignature(message, SecretKey)) { throw new Exception( "Computed signature for the payload does not match the signature supplied in the message. Message may have been tampered with."); } // add to the incoming message queue. caller will retrieve the messages on their own thread IncomingMessages.Enqueue(message); } catch (Exception ex) { Debug.Print("Error processing message from Sinric:\n" + ex + "\n"); } }