AWS SimpleDB - SignatureDoesNotMatch - PCL для приложения Xamarin
Я пытаюсь создать постоянную среду SimpleDB для компонента Xamarin. Я не могу использовать.NET SDK, так как не все необходимые сборки присутствуют в проекте PCL. По этой причине я пытаюсь создать запрос REST самостоятельно, но я продолжаю получать SignatureDoesNotMatch при попытке отправить мой запрос.
Может кто-нибудь помочь и посмотреть, если что-то не так с моим поколением подписей.
Вот просьба подписаться
Вот строка подписывается
POST\n sdb.amazonaws.com\n /\n &AWSAccessKeyId=AAAAAAAAAAAAAAAAAAAA&Action=PutAttributes&Attribute.1. % 3A00&Version=2009-04-15
Вот подписанный запрос.
Тест AWSAccessKeyId = AAAAAAAAAAAAAAAAAAAA Тест AWSSecretKey = BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
Я включил C# файлы моего хеширования и построителя запросов
public class PutAttributesRequestMarshaller
{
private const string ACTION = "PutAttributes";
private const string METHOD = "POST";
private const string SIGNATURE_METHOD = "HmacSHA256";
private const string SIGNATURE_VERSION = "2";
private const string VERSION = "2009-04-15";
private SortedDictionary<string, string> AttributesDic = new SortedDictionary<string, string> ();
private PutAttributesRequest request;
public PutAttributesRequestMarshaller (PutAttributesRequest request)
{
this.request = request;
for (int i = 0; i < request.Attributes.Count; i++) {
ReplaceableAttribute Attribute = request.Attributes [i];
AttributesDic.Add ("Attribute." + (i + 1) + ".Name", Attribute.Name);
AttributesDic.Add ("Attribute." + (i + 1) + ".Value", Attribute.Value);
if (Attribute.Replace.Value) {
AttributesDic.Add ("Attribute." + (i + 1) + ".Replace", Attribute.Replace.ToString ().ToLower ());
}
}
}
public String Marshal ()
{
StringBuilder sb = new StringBuilder ();
sb.Append ("https://" + Region + "/");
sb.Append ("?Action=" + ACTION);
sb.Append ("&DomainName=" + request.DomainName);
sb.Append ("&ItemName=" + request.ItemName);
sb.Append (Attributes);
sb.Append ("&Version=" + VERSION);
sb.Append ("&Timestamp=" + Timestamp);
string signature = GenerateSignature ();
string encoded = System.Net.WebUtility.UrlEncode (signature);
sb.Append ("&Signature=" + encoded);
sb.Append ("&SignatureVersion=" + SIGNATURE_VERSION);
sb.Append ("&SignatureMethod=" + SIGNATURE_METHOD);
sb.Append ("&AWSAccessKeyId=" + AWSAccessKeyId);
return sb.ToString ();
}
private string Attributes {
get {
StringBuilder sb = new StringBuilder ();
var enumerator = AttributesDic.GetEnumerator ();
while (enumerator.MoveNext ()) {
var entry = enumerator.Current;
sb.Append ("&");
sb.Append (System.Net.WebUtility.UrlEncode (entry.Key));
sb.Append ("=");
sb.Append (System.Net.WebUtility.UrlEncode (entry.Value));
}
return sb.ToString ();
}
}
private string AWSAccessKeyId {
get {
return ServiceContainer.Resolve<SimpleDBClient> ().AWSAccessKeyId;
}
}
private string AWSSecretKey {
get {
return ServiceContainer.Resolve<SimpleDBClient> ().AWSSecretKey;
}
}
private string Timestamp {
get {
DateTime withOutMili = DateTime.Now;
string formatted = withOutMili.ToString ("yyyy-MM-ddTHH:mm:sszzzzz");
string encoded = System.Net.WebUtility.UrlEncode (formatted);
return encoded;
}
}
public string Region {
get {
return ServiceContainer.Resolve<SimpleDBClient> ().Region;
}
}
private string GenerateSignature ()
{
StringBuilder sb = new StringBuilder ();
sb.Append (METHOD + "\n");
sb.Append (Region + "\n");
sb.Append ("/\n");
sb.Append ("&AWSAccessKeyId=" + AWSAccessKeyId);
sb.Append ("&Action=" + ACTION);
sb.Append (Attributes);
sb.Append ("&DomainName=" + request.DomainName);
sb.Append ("&ItemName=" + request.ItemName);
sb.Append ("&SignatureMethod=" + SIGNATURE_METHOD);
sb.Append ("&SignatureVersion=" + SIGNATURE_VERSION);
sb.Append ("&Timestamp=" + Timestamp);
sb.Append ("&Version=" + VERSION);
string signature = sb.ToString ();
ISHA256Service service = ServiceContainer.Resolve<ISHA256Service> ();
string hashed = service.CreateHash (signature, AWSSecretKey);
return hashed;
}
private SimpleDBClient Client {
get {
return ServiceContainer.Resolve<SimpleDBClient> ();
}
}
public string CreateHash (string message, string secret)
{
var encoding = new System.Text.ASCIIEncoding ();
byte[] keyByte = encoding.GetBytes (secret);
byte[] messageBytes = encoding.GetBytes (message);
using (var hmacsha256 = new HMACSHA256 (keyByte)) {
byte[] hashmessage = hmacsha256.ComputeHash (messageBytes);
return Convert.ToBase64String (hashmessage);
}
}
Заранее спасибо.
1 ответ
Я обнаружил несколько проблем с моим кодом, самая большая из которых заключалась в том, что я использовал 2 разные метки времени.