2015-02-13 2 views
1

Там, кажется, что-то не так с этой документацией: http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.htmlAmazon AWS S3 Browser Загрузить на PHP (AWS Signature Version 4)

Я последовал за ним точно и это похоже на работу. У меня всегда была ошибка SignatureDoesNotMatch. Однако авторизация v2 работает. Заставляет меня задаться вопросом, является ли это своего рода продуктом качества Alpha-stage.

Ниже представлен мой код php. Я пытался подражать примеру на этой странице: http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html

<?php 

$secret = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'; 

$datenow = '20130806'; 
$region = 'us-east-1'; 
$service = 's3'; 
$terminator = 'aws4_request'; 
$policy = '{ "expiration": "2013-08-07T12:00:00.000Z", 
    "conditions": [ 
    {"bucket": "examplebucket"}, 
    ["starts-with", "$key", "user/user1/"], 
    {"acl": "public-read"}, 
    {"success_action_redirect": "http://examplebucket.s3.amazonaws.com/successful_upload.html"}, 
    ["starts-with", "$Content-Type", "image/"], 
    {"x-amz-meta-uuid": "14365123651274"}, 
    ["starts-with", "$x-amz-meta-tag", ""], 

    {"x-amz-credential": "AKIAIOSFODNN7EXAMPLE/'.$datenow.'/'.$region.'/'.$service.'/'.$terminator.'"}, 
    {"x-amz-algorithm": "AWS4-HMAC-SHA256"}, 
    {"x-amz-date": "'.$datenow.'T000000Z" } 
    ] 
}'; 

$policy64 = base64_encode($policy); 

assert($policy64 == $policy64); 
$targetPolicy64 = 'eyAiZXhwaXJhdGlvbiI6ICIyMDEzLTA4LTA3VDEyOjAwOjAwLjAwMFoiLA0KICAiY29uZGl0aW9ucyI6IFsNCiAgICB7ImJ1Y2tldCI6ICJleGFtcGxlYnVja2V0In0sDQogICAgWyJzdGFydHMtd2l0aCIsICIka2V5IiwgInVzZXIvdXNlcjEvIl0sDQogICAgeyJhY2wiOiAicHVibGljLXJlYWQifSwNCiAgICB7InN1Y2Nlc3NfYWN0aW9uX3JlZGlyZWN0IjogImh0dHA6Ly9leGFtcGxlYnVja2V0LnMzLmFtYXpvbmF3cy5jb20vc3VjY2Vzc2Z1bF91cGxvYWQuaHRtbCJ9LA0KICAgIFsic3RhcnRzLXdpdGgiLCAiJENvbnRlbnQtVHlwZSIsICJpbWFnZS8iXSwNCiAgICB7IngtYW16LW1ldGEtdXVpZCI6ICIxNDM2NTEyMzY1MTI3NCJ9LA0KICAgIFsic3RhcnRzLXdpdGgiLCAiJHgtYW16LW1ldGEtdGFnIiwgIiJdLA0KDQogICAgeyJ4LWFtei1jcmVkZW50aWFsIjogIkFLSUFJT1NGT0ROTjdFWEFNUExFLzIwMTMwODA2L3VzLWVhc3QtMS9zMy9hd3M0X3JlcXVlc3QifSwNCiAgICB7IngtYW16LWFsZ29yaXRobSI6ICJBV1M0LUhNQUMtU0hBMjU2In0sDQogICAgeyJ4LWFtei1kYXRlIjogIjIwMTMwODA2VDAwMDAwMFoiIH0NCiAgXQ0KfQ=='; 
// echo base64_decode($targetPolicy64); 
// echo $policy64."\n".$targetPolicy64; 

assert($policy64 == $targetPolicy64); 

// At this point everything seems to work well. Converting the policy 
// to base64 resulted in exactly the same string with example. 
// The problem, however, happens when calculating the signature, 
// as shown below: 

$targetSignature = '21496b44de44ccb73d545f1a995c68214c9cb0d41c45a17a5daeec0b1a6db047'; 
$signature = ''; 

$hash1 = hash_hmac(
    'sha256', 
    $datenow, 
    "AWS4".$secret, 
    true 
); 

$hash2 = hash_hmac(
    'sha256', 
    $region, 
    $hash1, 
    true 
); 

$hash3 = hash_hmac(
    'sha256', 
    $service, 
    $hash2, 
    true 
); 

$signingKey = hash_hmac(
    'sha256', 
    $terminator, 
    $hash3, 
    true 
); 

$signature = base64_encode(hash_hmac(
    'sha256', 
    $policy64, 
    $signingKey, 
    true 
)); 


echo $signature."\n".$targetSignature; 
// This assertion never passed. 
assert($signature == $targetSignature); 

Я думал, что это была проблема, например, таким образом я попытался создать страницу загрузки образца браузера с точно такими же методами, но это не сработало.

Запуск кода подписи подписи здесь: PHP hash_hmac not matching AWS Signature 4 example однако, работает, поэтому я сомневаюсь, что проблема возникает при создании подписи, или это так?

Пожалуйста, помогите, любой.

ответ

-1
<?php 

// Fill These In! 
define('S3_BUCKET', ''); 
define('S3_KEY', ''); 
define('S3_SECRET', ''); 
define('S3_REGION', '');  // S3 region name: http://amzn.to/1FtPG6r 
define('S3_ACL', 'private'); // File permissions: http://amzn.to/18s9Gv7 
// Stop Here 

$algorithm = "AWS4-HMAC-SHA256"; 
$service = "s3"; 
$date = gmdate('Ymd\THis\Z'); 
$shortDate = gmdate('Ymd'); 
$requestType = "aws4_request"; 
$expires = '86400'; // 24 Hours 
$successStatus = '201'; 

$scope = [ 
    S3_KEY, 
    $shortDate, 
    S3_REGION, 
    $service, 
    $requestType 
]; 
$credentials = implode('/', $scope); 

$policy = [ 
    'expiration' => gmdate('Y-m-d\TG:i:s\Z', strtotime('+6 hours')), 
    'conditions' => [ 
     ['bucket' => S3_BUCKET], 
     ['acl' => S3_ACL], 
     [ 
      'starts-with', 
      '$key', 
      '' 
     ], 
     ['success_action_status' => $successStatus], 
     ['x-amz-credential' => $credentials], 
     ['x-amz-algorithm' => $algorithm], 
     ['x-amz-date' => $date], 
     ['x-amz-expires' => $expires], 
    ] 
]; 
$base64Policy = base64_encode(json_encode($policy)); 

// Signing Keys 
$dateKey = hash_hmac('sha256', $shortDate, 'AWS4' . S3_SECRET, true); 
$dateRegionKey = hash_hmac('sha256', S3_REGION, $dateKey, true); 
$dateRegionServiceKey = hash_hmac('sha256', $service, $dateRegionKey, true); 
$signingKey = hash_hmac('sha256', $requestType, $dateRegionServiceKey, true); 

// Signature 
$signature = hash_hmac('sha256', $base64Policy, $signingKey); 

?> 

<!doctype html> 
<html> 
    <head> 
     <meta charset="utf-8"> 
     <title>Direct Upload Example</title> 
     <style> 
      .progress { 
       position: relative; 
       width: 100%; 
       height: 15px; 
       background: #C7DA9F; 
       border-radius: 10px; 
       overflow: hidden; 
      } 
      .bar { 
       position: absolute; 
       top: 0; left: 0; 
       width: 0; height: 15px; 
       background: #85C220; 
      } 
      .bar.red { background: tomato; } 
     </style> 
    </head> 
    <body> 

     <!-- Direct Upload to S3 --> 
     <!-- URL prefix (//) means either HTTP or HTTPS (depending on which is being currently used) --> 
     <form action="//<?php echo S3_BUCKET . "." . $service . "-" . S3_REGION; ?>.amazonaws.com" 
       method="POST" 
       enctype="multipart/form-data" 
       class="direct-upload"> 

      <!-- Note: Order of these is Important --> 
      <input type="hidden" name="key" value="${filename}"> 
      <input type="hidden" name="acl" value="<?php echo S3_ACL; ?>"> 
      <input type="hidden" name="success_action_status" value="<?php echo $successStatus; ?>"> 
      <input type="hidden" name="policy" value="<?php echo $base64Policy; ?>"> 

      <input type="hidden" name="X-amz-algorithm" value="<?php echo $algorithm; ?>"> 
      <input type="hidden" name="X-amz-credential" value="<?php echo $credentials; ?>"> 
      <input type="hidden" name="X-amz-date" value="<?php echo $date; ?>"> 
      <input type="hidden" name="X-amz-expires" value="<?php echo $expires; ?>"> 
      <input type="hidden" name="X-amz-signature" value="<?php echo $signature; ?>"> 

      <input type="file" name="file"> 

      <!-- Progress Bar to show upload completion percentage --> 
      <div class="progress"><div class="bar"></div></div> 

     </form> 

     <!-- Used to Track Upload within our App --> 
     <form action="server.php" method="POST"> 
      <input type="hidden" name="upload_original_name" id="upload_original_name"> 
      <label for="upload_custom_name">Name:</label><br /> 
      <input type="text" name="upload_custom_name" id="upload_custom_name"><br /> 
      <input type="submit" value="Save"/> 
     </form> 

     <script src="//code.jquery.com/jquery-1.11.0.min.js"></script> 
     <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> 
     <script src="fileupload/jquery.fileupload.js"></script> 
     <script> 
      $(document).ready(function() { 
       $('.direct-upload').each(function() { 
        var form = $(this); 
        form.fileupload({ 
         url: form.attr('action'), 
         type: 'POST', 
         datatype: 'xml', 
         add: function (event, data) { 

          // Message on unLoad. 
          // Shows 'Are you sure you want to leave message', just to confirm. 
          window.onbeforeunload = function() { 
           return 'You have unsaved changes.'; 
          }; 

          // Actually submit to form, sending the data. 
          data.submit(); 
         }, 
         progress: function (e, data) { 
          // This is what makes everything really cool, thanks to that callback 
          // you can now update the progress bar based on the upload progress. 
          var percent = Math.round((data.loaded/data.total) * 100); 
          $('.bar').css('width', percent + '%'); 
         }, 
         fail: function (e, data) { 
          // Remove the 'unsaved changes' message. 
          window.onbeforeunload = null; 
          $('.bar').css('width', '100%').addClass('red'); 
         }, 
         done: function (event, data) { 
          window.onbeforeunload = null; 
          // Fill the name field with the file's name. 
          $('#upload_original_name').val(data.originalFiles[0].name); 
          $('#upload_custom_name').val(data.originalFiles[0].name); 
         } 
        }); 
       }); 
      }); 
     </script> 
    </body> 
</html> 

(https://www.designedbyaturtle.co.uk/2015/direct-upload-to-s3-using-aws-signature-v4-php/)

Работы для меня

Смежные вопросы