AWS S3签名不匹配问题求助(HTML表单上传场景)
Hey there! As your first AWS project, figuring out S3 signature issues can feel pretty overwhelming—let’s break down the most common fixes for this error, using your code as a starting point.
Common Issues & Fixes
1. Your Policy Document is Expired or Incomplete
Looking at your code, the $expiration is set to 2018-04-07T00:00:00Z—that’s way in the past! S3 will reject any policy that’s expired, so this is almost certainly one of your big problems.
Additionally, your policy snippet is truncated ("bucke..."). Make sure your full policy is valid JSON with no syntax errors, and includes all required conditions. For example, a complete policy might look like:
{ "expiration": "2024-12-31T00:00:00Z", "conditions": [ {"bucket": "your-full-bucket-name"}, {"success_action_redirect": "http://localhost/"}, ["starts-with", "$key", ""], ["content-length-range", 0, 10485760] ] }
Always validate your JSON to catch typos or missing brackets—even a single missing comma can break the signature.
2. Date/Time Values Must Be Accurate & Synchronized
For V2 signatures (which your code appears to use), the currentV2 (ISO 8601 format) and currentDate (YYYYMMDD) must:
- Match the actual current time (S3 rejects requests with timestamps more than 15 minutes off its server time)
- Be generated at the same time you create the policy and signature
Instead of hardcoding dates, use PHP’s DateTime class to generate dynamic, accurate values:
$expiration = (new DateTime('+1 hour'))->format('Y-m-d\TH:i:s\Z'); // Expire in 1 hour to avoid immediate expiration $currentV2 = (new DateTime())->format('Ymd\THis\Z'); $currentDate = (new DateTime())->format('Ymd');
3. Signature Generation Steps Are Incorrect
The signature is created by following these exact steps:
- Base64-encoding the policy document (ensure it’s URL-safe by replacing
+with-,/with_, and removing trailing=). - Hashing the encoded policy with your AWS Secret Access Key using HMAC-SHA1.
- Base64-encoding the hashed result (again, make it URL-safe).
Double-check that:
- You’re using the correct AWS Secret Access Key from your config (no typos, and never hardcode it publicly!)
- You’re using
hash_hmac('sha1', ..., true)to get raw binary output before base64 encoding—omitting thetrueflag will give you a hex string instead of the required binary data.
Here’s a corrected snippet for generating the signature:
// Encode policy to base64 and make URL-safe $base64Policy = base64_encode($policydoc); $base64Policy = str_replace(['+', '/', '='], ['-', '_', ''], $base64Policy); // Generate signature $signature = base64_encode(hash_hmac('sha1', $base64Policy, $conf['aws_secret_key'], true)); $signature = str_replace(['+', '/', '='], ['-', '_', ''], $signature);
4. HTML Form Fields Must Match Policy Conditions
Every field in your form must align exactly with the conditions in your policy:
- The form’s
actionmust be your S3 bucket URL (e.g.,https://your-bucket.s3.amazonaws.com/) - Hidden fields like
AWSAccessKeyId,policy,signature, andsuccess_action_redirectmust match the values you generated - Ensure the form uses
method="post"andenctype="multipart/form-data"
Example working form:
<form action="https://<?php echo $bucket; ?>.s3.amazonaws.com/" method="post" enctype="multipart/form-data"> <input type="hidden" name="AWSAccessKeyId" value="<?php echo $conf['aws_access_key']; ?>"> <input type="hidden" name="policy" value="<?php echo $base64Policy; ?>"> <input type="hidden" name="signature" value="<?php echo $signature; ?>"> <input type="hidden" name="success_action_redirect" value="<?php echo $success_action_redirect; ?>"> <input type="hidden" name="key" value="${filename}"> <!-- Add a prefix like "uploads/${filename}" if you want to organize files --> <input type="file" name="file"> <button type="submit">Upload File</button> </form>
Quick Recap of Priorities
- Update the expiration date to a future time (never use past dates!)
- Complete your policy document with valid JSON and the correct bucket name
- Verify signature generation uses the right key and steps
- Align form fields exactly with policy conditions
内容的提问来源于stack exchange,提问作者user2763309

