2010-02-17 20 views
7

有沒有人使用.net實際上計算出如何成功簽署與CloudFront私有內容一起使用的簽名?經過幾天的嘗試,我所能得到的是Access Denied。如何使用罐裝策略對私有內容訪問的Amazon CloudFront簽名進行加密

我一直在用下面的代碼的變化,並嘗試使用OpenSSL.Net和AWSSDK但不具有RSA-SHA1的標誌方法呢。

簽名(數據)看起來像這樣

{"Statement":[{"Resource":"http://xxxx.cloudfront.net/xxxx.jpg","Condition":​{"DateLessThan":​{"AWS:EpochTime":1266922799}}}]} 

更新:通過在上述簽名中除去1個空間解決所有這一切。

如果只有我早點注意到它!

此方法嘗試簽署在罐裝url中使用的簽名。所以這些變體已經包括了在has中使用的填充,並且在簽名之前反轉字節[],就像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的罐裝政策網址驗證的內容設置。他們是如何做到的呢?

任何想法將不勝感激。由於

+0

切特, 能否詳細說明您的解決方案? 我想在PostSharp下載管理器(現在使用S3 + CloudFront公共內容)上實現私人內容。 我特別感興趣的是您如何使用OpenSslKey將Amazon PEM轉換爲XML。你能分享一些鏈接嗎? 謝謝。 -gael – 2010-03-13 15:36:06

+0

要轉換PEM到XML,你可以抓住從http://www.jensign.com/opensslkey/index.html 源或OpenSSLKey的comiled版本如果您下載然後剛從opensslkey.exe運行cmd行並按照提示進行操作 – Chet 2010-03-17 20:33:42

+0

謝謝 - 使用該信息實現並不困難。但是,我建議使用某些GUI正確配置S3/CloudFront進行測試,然後嘗試使用代碼執行相同的操作。 – 2010-03-30 12:22:58

回答

6

這裏是如果,如果有興趣的人的完整代碼:我已經做了什麼,我不得不做的就是它的工作博客中

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

} 
+0

小心過期傳入的時間。它需要與UTC時間相關。 – beckelmw 2010-03-30 18:32:47

相關問題