2015-03-19 146 views
0

我正在嘗試使用AWS S3服務以Swift語言託管我的iOS應用程序的圖像。 在這一步,我只是試圖簡單地發佈POST請求的PNG圖像。 在任何針對AWS S3的POST請求中,我們都需要創建一個授權標頭,其中包含驗證此請求的信息。用亞馬遜需要的HMAC SHA256編碼數據我使用GitHub項目作爲我的子項目從這個鏈接:https://github.com/krzyzanowskim/CryptoSwift 這幫助我加密簽名但是當我試圖發送這個請求我收到一個錯誤,說:「SignatureDoesNotMatchThe請求籤名我們計算的結果與您提供的簽名不符,請檢查您的密鑰和簽名方法。「在Swift中製作亞馬遜網絡服務S3 POST請求

這裏是我的代碼:

 var img = UIImage(named: "myImage.png") 
     var imageData : NSData = UIImageJPEGRepresentation(img, 1.0) 

     let key = "mybucketname" 

     let url = NSURL(string:"http://mybucket.s3.amazonaws.com/") 
     var request = NSMutableURLRequest(URL: url!)   
     request.HTTPMethod = "POST" 

     let uniqueId = NSProcessInfo.processInfo().globallyUniqueString 
     var postBody:NSMutableData = NSMutableData() 
     var boundary:String = "------WebKitFormBoundary\(uniqueId)" 
     request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField:"Content-Type") 
//  I am trying to generate a date stamp compatible for request 
     let date = NSDate() 
     let formatter = NSDateFormatter() 
     formatter.timeStyle = .ShortStyle 
     formatter.stringFromDate(date) 

     var dateKey = ["AWS4"+"My AWSSecretKey","20150317"] 
//  Here is the signature that I'm trying to make 
     var signature = "My AWSSecretKey".sha256()?.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions()) 
     request.addValue("AWS MYAWSACCESSKEYID:\(signature)", forHTTPHeaderField: "Authorization") 
     request.addValue("Wed, 18 Mar 2015 20:39:27 +0000", forHTTPHeaderField: "Date") 
     request.addValue(key, forHTTPHeaderField:"key") 
     request.addValue("\(postBody.length)", forHTTPHeaderField:"Content-Length") 


     postBody.appendData("--\(boundary)\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
     postBody.appendData("Content-Type: image/png\r\n".dataUsingEncoding(NSUTF8StringEncoding)!) 
     postBody.appendData(imageData) 
     var postData = String() 
     postData += "\r\n" 
     postData += "\r\n--\(boundary)--\r\n" 
     postBody.appendData(postData.dataUsingEncoding(NSUTF8StringEncoding)!) 
     request.HTTPBody = postBody 

     var error: NSError? 
     let session = NSURLSession.sharedSession() 
     var task = session.dataTaskWithRequest(request, completionHandler: { (data, response, err) -> Void in 
      var stringData = NSString(data: data, encoding: NSUTF8StringEncoding) 

      var conversionError: NSError? 
      var jsonDictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableLeaves, error: &conversionError) as? NSDictionary 
     }) 
     task.resume() 

我需要找出如何使一個適當的簽名,我應該如何自我火一次使用這樣的工具對其進行加密。

回答

0

你不應該在你的應用程序中硬編碼一個祕密密鑰 - 這會否定其安全性。我建議從生成你自己的服務器的密鑰(例如,使用優秀的S3Direct Django的模塊),然後獲取關鍵是這樣的:

let filename = "myfile.mp4" 
let requestUrl = Constants.my_own_server+"/s3direct/get_upload_params/" 


println("Uploading file of name ***" + filename + "***") 

let defaults = NSUserDefaults.standardUserDefaults() 
let authToken : String = defaults.stringForKey("token")! 

let manager = Manager.sharedInstance 
manager.session.configuration.HTTPAdditionalHeaders = [ 
"Authorization": "Token " + authToken 
] 

let parameters : [ String : AnyObject] = [ 
    "type": "video/mp4", 
    "name": filename, 
    "dest": "vids" 
] 

Alamofire.request(.POST, requestUrl, parameters: parameters).response(serializer: Request.JSONResponseSerializer(), completionHandler: { (request, response, object, error) -> Void in 
    //println(object) 
    //println(error) 
    if (error == nil) { 
     self.uploadFile(videoData!, parameters: object as! [ String : String], filename: filename) 
    } 
    else { 
     print("Failed to sign file") 
    } 
}) 

祝你好運 - 我發現這個特別的堆棧異常痛苦得到工作。