在C#中验证Amazon SNS签名

时间:2014-12-19 09:02:14

标签: c# cryptography amazon-sns

我有一个ASP.NET端点,我收到Amazon SNS消息。我想验证我收到的签名以及这些消息,并遵循http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.example.java.html指南尝试匹配C#中的Java代码。这是我到目前为止所做的事情(我只对验证通知感兴趣,而不是订阅确认):

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());
}

rsa.VerifyData()步骤返回false。我已经在Java中构建了这个示例,在这里它可以正常工作,我试图验证相同的消息,以及我用于C#的相同证书。

在这里,我看到两个程序的不同之处。 C#GetMessageBytes字节数组返回637字节,而Java等效getMessageBytesToSign返回627字节。不幸的是,出于安全原因,我无法在此处发布消息内容。我的Java设置默认使用windows-1252字符集,但即使我将C#编码改为,字节数仍然是637。我不熟悉编码和C#与Java之间的差异所以我不知道它是否具有任何重要性。

关于如何更改C#的任何想法?

3 个答案:

答案 0 :(得分:1)

Java代码以\n结尾。 C#版本(StringBuilder.AppendLine())使用\r\n

答案 1 :(得分:0)

这种方式对我有用:

var sb = new StringBuilder();

sb.Append("Message\n");
sb.Append(notificationWrapper.Message).Append("\n");
sb.Append("MessageId\n");
sb.Append(notificationWrapper.MessageId).Append("\n");

if (notificationWrapper.Subject != null)
{
    sb.Append("Subject\n");
    sb.Append(notificationWrapper.Subject).Append("\n");
}

sb.Append("Timestamp\n");
sb.Append(notificationWrapper.Timestamp).Append("\n");
sb.Append("TopicArn\n");
sb.Append(notificationWrapper.TopicArn).Append("\n");
sb.Append("Type\n");
sb.Append(notificationWrapper.Type).Append("\n");

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

答案 2 :(得分:0)

Amazon.SimpleNotificationService.Util.Message.ParseMessage(SNS_MESSAGE).IsMessageSignatureValid()