似乎有什么不对的文件:的http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html
我跟着它准确,它似乎工作。我总是SignatureDoesNotMatch错误。 V2授权的作品虽然。让我不知道这某种阿尔法级品质的产品。
下面是我的PHP code。我试图模仿的例子在此页: HTTP:/ /docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html
< PHP
$秘密='wJalrXUtnFEMI / K7MDENG / bPxRfiCYEXAMPLEKEY;
$ datenow ='20130806';
$区域='美国东1;
$服务='S3';
$终止='aws4_request';
$政策='{过期:2013-08-07T12:00:00.000Z
条件:
{斗:examplebucket},
[开始,以,$关键,用户/用户1 /],
{以acl:大众阅读的},
{success_action_redirect:http://examplebucket.s3.amazonaws.com/successful_upload.html},
[开始,以,$内容类型,图像/],
{的x AMZ-元的uuid:14365123651274},
[开始 - 用,$的x AMZ-meta标记,],
{X-AMZ-凭据:。。。AKIAIOSFODNN7EXAMPLE /'.$ datenow'/'$区'/'$服务'/'$终结者'。},
{的x AMZ-算法:AWS4-HMAC-SHA256},
{X-AMZ-日期:'$ datenow.'T000000Z。}
]
};
$ policy64 = base64_en code($政策);
断言($ policy64 == $ policy64);
$ targetPolicy64 = 'eyAiZXhwaXJhdGlvbiI6ICIyMDEzLTA4LTA3VDEyOjAwOjAwLjAwMFoiLA0KICAiY29uZGl0aW9ucyI6IFsNCiAgICB7ImJ1Y2tldCI6ICJleGFtcGxlYnVja2V0In0sDQogICAgWyJzdGFydHMtd2l0aCIsICIka2V5IiwgInVzZXIvdXNlcjEvIl0sDQogICAgeyJhY2wiOiAicHVibGljLXJlYWQifSwNCiAgICB7InN1Y2Nlc3NfYWN0aW9uX3JlZGlyZWN0IjogImh0dHA6Ly9leGFtcGxlYnVja2V0LnMzLmFtYXpvbmF3cy5jb20vc3VjY2Vzc2Z1bF91cGxvYWQuaHRtbCJ9LA0KICAgIFsic3RhcnRzLXdpdGgiLCAiJENvbnRlbnQtVHlwZSIsICJpbWFnZS8iXSwNCiAgICB7IngtYW16LW1ldGEtdXVpZCI6ICIxNDM2NTEyMzY1MTI3NCJ9LA0KICAgIFsic3RhcnRzLXdpdGgiLCAiJHgtYW16LW1ldGEtdGFnIiwgIiJdLA0KDQogICAgeyJ4LWFtei1jcmVkZW50aWFsIjogIkFLSUFJT1NGT0ROTjdFWEFNUExFLzIwMTMwODA2L3VzLWVhc3QtMS9zMy9hd3M0X3JlcXVlc3QifSwNCiAgICB7IngtYW16LWFsZ29yaXRobSI6ICJBV1M0LUhNQUMtU0hBMjU2In0sDQogICAgeyJ4LWFtei1kYXRlIjogIjIwMTMwODA2VDAwMDAwMFoiIH0NCiAgXQ0KfQ==';
//回声base64_de code($ targetPolicy64);
//回声$ policy64\ N$ targetPolicy64。;
断言($ policy64 == $ targetPolicy64);
//此时一切似乎运作良好。转换政策
//为base64导致完全相同的字符串例子。
//的问题,但是,会发生计算签名时,
//如下所示:
$ targetSignature ='21496b44de44ccb73d545f1a995c68214c9cb0d41c45a17a5daeec0b1a6db047';
$签字='';
$ HASH1 = hash_hmac(
SHA256,
$ datenow,
AWS4。$的秘密,
真正
);
$ HASH2 = hash_hmac(
SHA256,
$区域,
$ HASH1,
真正
);
$ hash3 = hash_hmac(
SHA256,
$的服务,
$ HASH2,
真正
);
$ signingKey = hash_hmac(
SHA256,
$终结者,
$ hash3,
真正
);
$签字= base64_en code(hash_hmac(
SHA256,
$ policy64,
$ signingKey,
真正
));
回声$签字\ N$ targetSignature。;
//这种说法从来没有通过。
断言($签名== $ targetSignature);
我还以为是这个例子的问题,所以我试着用完全相同的方法创建一个样本浏览器上传页面,但它也不能工作。
运行签名签署code在这里:PHP hash_hmac不匹配AWS签名但4例如的,工作的,所以我怀疑的问题是签名创建过程中,是这样吗?
请帮忙,任何人。
解决方案 < PHP
//填补这些了!
定义('S3_BUCKET','');
定义('S3_KEY','');
定义('S3_SECRET','');
定义('S3_REGION',''); // S3地区名称:http://amzn.to/1FtPG6r
定义(S3_ACL,私人); //文件权限:http://amzn.to/18s9Gv7
// 停在这里
$算法=AWS4-HMAC-SHA256;
$服务=S3;
$日期= gmdate(YMD \本\ Z');
$ shortDate = gmdate('年月日');
$的RequestType =aws4_request;
$到期='86400'; // 24小时
$ successStatus ='201';
$范围= [
S3_KEY,
$ shortDate,
S3_REGION,
$的服务,
$的RequestType
]。
$凭证=破灭('/',$范围);
$政策= [
'过期'=> gmdate(Y-M-D \ TG:我:秒\ Z',的strtotime('+ 6小时)),
'条件'=> [
['斗'=> S3_BUCKET]
['的ACL'=> S3_ACL]
[
开头,以,
$钥匙,
''
]
['success_action_status'=> $ successStatus]
['的X AMZ-凭证'=> $凭据]
['的X AMZ-算法'=> $算法]
['的X AMZ-日期=> $日期]
['X-AMZ-过期'=> $过期]
]
]。
$ base64Policy = base64_en code(json_en code($政策));
//签名密钥
$ dateKey = hash_hmac('SHA256',$ shortDate,AWS4S3_SECRET,真的。);
$ dateRegionKey = hash_hmac(SHA256,S3_REGION,$ dateKey,真正的);
$ dateRegionServiceKey = hash_hmac('SHA256',$服务,$ dateRegionKey,真正的);
$ signingKey = hash_hmac('SHA256',$请求类型,$ dateRegionServiceKey,真正的);
// 签名
$签字= hash_hmac('SHA256',$ base64Policy,$ signingKey);
?>
<!DOCTYPE HTML>
< HTML>
< HEAD>
<元字符集=utf-8>
<冠军>直接上传实例< /标题>
<风格>
。进展 {
位置:亲属;
宽度:100%;
高度:15px的;
背景:#C7DA9F;
边界半径:10px的;
溢出:隐藏;
}
。酒吧 {
位置:绝对的;
顶部:0;左:0;
宽度:0;高度:15px的;
背景:#85C220;
}
.bar.red {背景:番茄; }
< /风格>
< /头>
<身体GT;
<! - 直接上传到S3 - >
<! - URL preFIX(//)表示HTTP或HTTPS(目前正在使用取决于哪个) - >
<形式的行动=?//< PHP的回声S3_BUCKET。$的服务。 - S3_REGION;> .amazonaws.com?
方法=POST
ENCTYPE =的multipart / form-data的
类=直接上传>
!< - 注:订单,这些是非常重要的 - >
<输入类型=隐藏名称=键值=$ {文件名}>
<输入类型=隐藏名称=控制列表,acl值=< PHP的回声S3_ACL;>中>
<输入类型=隐藏名称=success_action_status值=< PHP的echo $ successStatus;>中>
<输入类型=隐藏名称=政策值=< PHP的echo $ base64Policy;>中>
<输入类型=隐藏名称=X-AMZ-算法值=< PHP的echo $算法;>中>
<输入类型=隐藏名称=X-AMZ-凭证值=< PHP的echo $凭证;>中>
<输入类型=隐藏名称=X-AMZ-日值=< PHP的echo $日期;?>>
<输入类型=隐藏名称=X-AMZ-过期值=< PHP的echo $到期;>中>
<输入类型=隐藏名称=X-AMZ-签名值=<?PHP的回声$签字;>中>
<输入类型=文件名称=文件>
<! - 进度条显示上传完成比例 - >
< DIV CLASS =进步>< DIV CLASS =酒吧>< / DIV>< / DIV>
< /形式GT;
<! - 使用我们的应用程序中跟踪上传 - >
<形式的行动=server.php方法=POST>
<输入类型=隐藏名称=upload_original_nameID =upload_original_name>
<标签=upload_custom_name>名称:< /标签>< BR />
<输入类型=文本名称=upload_custom_nameID =upload_custom_name>< BR />
<输入类型=提交值=保存/>
< /形式GT;
<脚本的src =// code.jquery.com / jQuery的-1.11.0.min.js>< / SCRIPT>
<脚本的src =// code.jquery.com / UI / 1.10.4 / jQuery的-ui.js>< / SCRIPT>
<脚本SRC =文件上传/ jquery.fileupload.js>< / SCRIPT>
<脚本>
$(文件)。就绪(函数(){
$('。直接上传)。每个(函数(){
变种形式= $(本);
form.fileupload({
网址:form.attr(行动),
键入:POST,
数据类型:XML,
地址:功能(事件数据){
//在卸载的消息。
//显示您确定要离开的消息,只是为了确认。
window.onbeforeunload =功能(){
返回你有未保存的更改。;
};
//实际上向形成,发送数据。
data.submit();
},
进展情况:功能(即数据){
//这是什么使一切真的很酷,这要归功于回调
//你现在可以更新基于上传进度的进度条。
变种百分比= Math.round((data.loaded / data.total)* 100);
$('巴')的CSS('宽',百分比+'%')。
},
失败:功能(即数据){
//删除未保存的更改的消息。
window.onbeforeunload = NULL;
$('巴')的CSS('宽','100%')addClass('红')。
},
完成:功能(事件数据){
window.onbeforeunload = NULL;
//与文件的名称填写名称字段。
$('#upload_original_name)VAL(data.originalFiles [0]。名称);
$('#upload_custom_name)VAL(data.originalFiles [0]。名称);
}
});
});
});
< / SCRIPT>
< /身体GT;
< / HTML>
(https://www.designedbyaturtle.co.uk/2015/direct-upload-to-s3-using-aws-signature-v4-php/)
我的作品
There seems to be something wrong with this documentation: http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html
I followed it exactly and it does seem to work. I always got SignatureDoesNotMatch error. v2 authorization works though. Makes me wonder if this some kind of Alpha-stage quality product.
Below is my php code. I tried to mimic the example in this page: 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);
I thought it was the problem of the example so I tried creating a sample browser upload page with exactly the same methods, but it did not work either.
Running the signature signing code here: PHP hash_hmac not matching AWS Signature 4 example however, works, so I doubt the issue is during signature creation, or is it?
Please help, anyone.
解决方案<?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/)
Works for me