Search code examples
c#amazon-web-servicesencodingrsakey-management

AWS Signature, Encoding, Verification


I have an POCO that I am generating signature for using AWS KeyManagementService

var signResponse= await client.SignAsync(new Amazon.KeyManagementService.Model.SignRequest()
        {
            KeyId = "keyid",
            MessageType = MessageType.RAW,
            SigningAlgorithm = SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_256,
            Message = new System.IO.MemoryStream(JsonSerializer.Serialize(item).ToByteArray())
        });

I then convert sig MemoryStream to string and save in the database

string sig = Encoding.Unicode.GetString(response.Signature.ToArray());

Upon retrieval of the object (another request) I use verify signature

var verifyResponse = await client.VerifyAsync(new Amazon.KeyManagementService.Model.VerifyRequest()
        {
            KeyId = "keyid",
            MessageType = MessageType.RAW,
            SigningAlgorithm = SigningAlgorithmSpec.RSASSA_PKCS1_V1_5_SHA_256,
            Message = new System.IO.MemoryStream(JsonSerializer.Serialize(item).ToByteArray()),
            Signature = new System.IO.MemoryStream(Encoding.Unicode.GetBytes(sig ?? ""))
        });

and unfortunately it fails, as in signature isn't verified. If i put these two calls right one after the other and set the Signature of the VerifyRequest to signReponse.Signature verification is successful.

This leads me to believe it has something to do with encoding/decoding of the signature stream to store in in DB. I tried all the encodings available in Encoding.

Am I missing something conceptual? How should a signature be stored in this situation?


Solution

  • You seem to be interpreting the signature as a series of Unicode code points (using Unicode.GetString(byte[])). It's not. It's just binary data. Probably should be encoding it with Convert.ToBase64String(byte[]) instead.