Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verifying Amazon SNS signatures in C#

I have an ASP.NET endpoint where I receive Amazon SNS messages. I want to verify the signatures I receive along with those messages and have followed the guide at http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.example.java.html trying to match the Java code in C#. Here's what I have so far (I'm only interested in validating notifications, not subscription confirmations):

private X509Certificate2 cert;        

// cert is from constructor...

private bool IsValidMessageSignature(AmazonMessage msg)
{
    // Verify the signature
    var rsa = (RSACryptoServiceProvider)cert.PublicKey.Key;
    var msgBytes = GetMessageBytes(msg);
    var signedBytes = Convert.FromBase64String(msg.Signature);
    return rsa.VerifyData(msgBytes, CryptoConfig.MapNameToOID("SHA1"), signedBytes);
}

private byte[] GetMessageBytes(AmazonMessage msg)
{
    // Construct message string
    var sb = new StringBuilder();
    sb.AppendLine("Message");
    sb.AppendLine(msg.Message);
    sb.AppendLine("MessageId");
    sb.AppendLine(msg.MessageId);
    if (msg.Subject != null)
    {
        sb.AppendLine("Subject");
        sb.AppendLine(msg.Subject);
    }
    sb.AppendLine("Timestamp");
    sb.AppendLine(msg.Timestamp);
    sb.AppendLine("TopicArn");
    sb.AppendLine(msg.TopicArn);
    sb.AppendLine("Type");
    sb.AppendLine(msg.Type);

    return Encoding.UTF8.GetBytes(sb.ToString());
}

The rsa.VerifyData() step returns false. I have built the example in Java as well, and here it works fine with the same message I'm trying to validate, and the same certificate that I'm using for C#.

Here's where the two programs differ as far as I can see. The C# GetMessageBytes byte-array returns 637 bytes, while the Java equivalent getMessageBytesToSign returns 627 bytes. Unfortunately I cannot post the message contents here for security reasons. My Java setup uses the windows-1252 charset by default, but even if I change the C# encoding to that the byte-array is still 637 in size. I'm not that experienced with encodings and the differences between C# and Java so I don't know if it's of any importance though.

Any ideas as to how my C# should be changed?

like image 712
soren.qvist Avatar asked Dec 19 '14 09:12

soren.qvist


1 Answers

Amazon.SimpleNotificationService.Util.Message.ParseMessage(SNS_MESSAGE).IsMessageSignatureValid()
like image 92
Timothy Gonzalez Avatar answered Oct 12 '22 04:10

Timothy Gonzalez