У кого-либо есть использование .NET, на самом деле разработанный, как успешно поставить подпись для использования с CloudFront частного содержания? После нескольких дней попыток все, что я могу получить, является Доступом запрещен.
Я работал с изменениями следующего кода и также попытался использовать OpenSSL.Net и AWSSDK, но это еще не имеет метода знака для RSA-SHA1.
Подпись (данные) похожа на это
{"Statement":[{"Resource":"http://xxxx.cloudfront.net/xxxx.jpg","Condition":{"DateLessThan":{"AWS:EpochTime":1266922799}}}]}
Обновление: Решенный все это путем удаления одиночного пробела в вышеупомянутой подписи.
Если только я заметил его ранее!
Этот метод пытается поставить подпись для использования в консервированном URL. Таким образом изменений включали chanding дополнение, используемое в и также инвертировании байта [] прежде, чем подписаться, поскольку apprently OpenSSL делает это этот путь.
public string Sign(string data)
{
using (SHA1Managed SHA1 = new SHA1Managed())
{
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
RSACryptoServiceProvider.UseMachineKeyStore = false;
// Amazon PEM converted to XML using OpenSslKey
provider.FromXmlString("<RSAKeyValue><Modulus>.....");
byte[] plainbytes = System.Text.Encoding.UTF8.GetBytes(data);
byte[] hash = SHA1.ComputeHash(plainbytes);
//Array.Reverse(sig); // I have see some examples that reverse the hash
byte[] sig = provider.SignHash(hash, "SHA1");
return Convert.ToBase64String(sig);
}
}
Его полезной, чтобы отметить, что я проверил содержание, является установка правильно в S3 и CloudFront путем генерации CloudFront консервированный URL политики с помощью моего Проводника CloudBerry. Как они делают это?
Любые идеи очень ценились бы.Спасибо
Вот полный код, если кому интересно:
internal class CloudFrontSecurityProvider
{
private readonly RSACryptoServiceProvider privateKey;
private readonly string privateKeyId;
private readonly SHA1Managed sha1 = new SHA1Managed();
public CloudFrontSecurityProvider(string privateKeyId, string privateKey)
{
this.privateKey = new RSACryptoServiceProvider();
RSACryptoServiceProvider.UseMachineKeyStore = false;
this.privateKey.FromXmlString( privateKey );
this.privateKeyId = privateKeyId;
}
private static int GetUnixTime(DateTime time)
{
DateTime referenceTime = new DateTime(1970, 1,1);
return (int) (time - referenceTime).TotalSeconds;
}
public string GetCannedUrl(string url, DateTime expiration)
{
string expirationEpoch = GetUnixTime( expiration ).ToString();
string policy =
@"{""Statement"":[{""Resource"":""<url>"",""Condition"":{""DateLessThan"":{""AWS:EpochTime"":<expiration>}}}]}".
Replace( "<url>", url ).
Replace( "<expiration>", expirationEpoch );
string signature = GetUrlSafeString( Sign( policy ) );
return url + string.Format("?Expires={0}&Signature={1}&Key-Pair-Id={2}", expirationEpoch, signature, this.privateKeyId);
}
private static string GetUrlSafeString(byte[] data)
{
return Convert.ToBase64String( data ).Replace( '+', '-' ).Replace( '=', '_' ).Replace( '/', '~' );
}
private byte[] Sign(string data)
{
byte[] plainbytes = Encoding.UTF8.GetBytes(data);
byte[] hash = sha1.ComputeHash(plainbytes);
return this.privateKey.SignHash(hash, "SHA1");
}
}