Sorry it was my mistake. I was still using the uri
generated from aws_sdk_s3
let presigned = self
.client
.put_object()
.bucket(bucket)
.key(file_path)
.content_type("image/")
.presigned(
PresigningConfig::builder()
.expires_in(Duration::from_secs(60 * 5))
.build()
.expect("less than one week"),
)
.await
.map_err(|err| {
return StorageError::PresignPutError(err.to_string());
})?;
I tried following the guide exactly but I’m now getting SignatureDoesNotMatch
error.
Policy json string (excluded content-length-range
for now):
"{\"conditions\":[{\"bucket\":\"empty-meadow-1162\"},[\"starts-with\",\"$key\",\"test/\"],{\"success_action_redirect\":\"http//localhost:8000/\"},[\"starts-with\",\"$Content-Type\",\"image/\"],{\"x-amz-meta-uuid\":\"8da4d7e3-0cc9-45b2-9095-8e89951c9dec\"},{\"x-amz-credential\":\"tid_gLhbNjKKAdmgroOtRZikcwRzIuQFLWrXdVnqNqgioxwxZEHDcY/20250702/auto/s3/aws4_request\"},{\"x-amz-algorithm\":\"AWS4-HMAC-SHA256\"},{\"x-amz-date\":\"20250702T212531Z\"}],\"expiration\":\"2025-07-02T21:25:31.579165529Z\"}"
This is my html form:
<form action="https://empty-meadow-1162.fly.storage.tigris.dev/" method="post" enctype="multipart/form-data">
<input type="hidden" name="success_action_redirect" value="http//localhost:8000/">
Key to upload:
<input type="input" name="key" value="test/randommmm.png"><br>
<input type="hidden" name="Content-Type" value="image/">
<input type="hidden" name="x-amz-meta-uuid" value="8da4d7e3-0cc9-45b2-9095-8e89951c9dec">
<input type="hidden" name="X-Amz-Credential" value="tid_gLhbNjKKAdmgroOtRZikcwRzIuQFLWrXdVnqNqgioxwxZEHDcY/20250702/auto/s3/aws4_request">
<input type="hidden" name="X-Amz-Algorithm" value="AWS4-HMAC-SHA256">
<input type="hidden" name="X-Amz-Date" value="20250702T212531Z">
<input type="hidden" name="Policy" value="eyJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJlbXB0eS1tZWFkb3ctMTE2MiJ9LFsic3RhcnRzLXdpdGgiLCIka2V5IiwidGVzdC8iXSx7InN1Y2Nlc3NfYWN0aW9uX3JlZGlyZWN0IjoiaHR0cC8vbG9jYWxob3N0OjgwMDAvIn0sWyJzdGFydHMtd2l0aCIsIiRDb250ZW50LVR5cGUiLCJpbWFnZS8iXSx7IngtYW16LW1ldGEtdXVpZCI6IjhkYTRkN2UzLTBjYzktNDViMi05MDk1LThlODk5NTFjOWRlYyJ9LHsieC1hbXotY3JlZGVudGlhbCI6InRpZF9nTGhiTmpLS0FkbWdyb090Ulppa2N3UnpJdVFGTFdyWGRWbnFOcWdpb3h3eFpFSERjWS8yMDI1MDcwMi9hdXRvL3MzL2F3czRfcmVxdWVzdCJ9LHsieC1hbXotYWxnb3JpdGhtIjoiQVdTNC1ITUFDLVNIQTI1NiJ9LHsieC1hbXotZGF0ZSI6IjIwMjUwNzAyVDIxMjUzMVoifV0sImV4cGlyYXRpb24iOiIyMDI1LTA3LTAyVDIxOjI1OjMxLjU3OTE2NTUyOVoifQ==">
<input type="hidden" name="X-Amz-Signature" value="0QI3yXk+3ekGl/7v0qQZUFpX8edl+Awb1ajafHZnz7Q=">
File:
<input type="file" name="file"> <br>
<input type="submit" name="submit" value="Upload to Tigris">
</form>
And I’m getting the signature like this:
use base64::{engine::general_purpose::STANDARD, Engine as _};
{
let policy_as_hex = STANDARD.encode(&aws_policy_string);
let signature = STANDARD.encode(hmac_sha256(
hmac_sha256(
hmac_sha256(
hmac_sha256(
hmac_sha256(format!("AWS4{}", secret_access_key), date.to_string()),
"auto",
),
"s3",
),
"aws4_request",
),
&policy_as_hex,
));
}
where hmac_sha256:
use sha2::Sha256;
use hmac::{Hmac, Mac};
type HmacSha256 = Hmac<Sha256>;
fn hmac_sha256(key: impl AsRef<[u8]>, message: impl AsRef<[u8]>) -> impl AsRef<[u8]> {
let mut mac = HmacSha256::new_from_slice(key.as_ref()).expect("HMAC can take key of any size.");
mac.update(message.as_ref());
let hmac = mac.finalize().into_bytes();
return hmac;
}
I’m not sure where my mistake is. I tried using the policy json string
and secret_access_key
from the guide as inputs but I got a different signature string.
#[test]
fn signature_matches() {
let test_policy_as_hex = STANDARD.encode("{\"expiration\":\"2024-03-30T12:00:00.000Z\",\"conditions\":[{\"bucket\":\"my-user-images\"},[\"starts-with\",\"$key\",\"images1/\"],{\"success_action_redirect\":\"https://your-website.com/success.html\"},[\"starts-with\",\"$Content-Type\",\"image/\"],{\"x-amz-meta-uuid\":\"465888667\"},{\"x-amz-credential\":\"tid_example_key_id/20240330/auto/s3/aws4_request\"},{\"x-amz-algorithm\":\"AWS4-HMAC-SHA256\"},{\"x-amz-date\":\"20240330T000000Z\"}]}");
let test_signature = STANDARD.encode(hmac_sha256(
hmac_sha256(
hmac_sha256(
hmac_sha256(
hmac_sha256(format!("AWS4{}", "tsec_example_H3CYVqDGmFxdXGlruqb16mS22qj59Ag9H3CYVqDGmFxdXGlruqb16mS22qj59"), "20240330"),
"auto",
),
"s3",
),
"aws4_request",
),
&test_policy_as_hex,
));
assert_eq!(
&test_signature,
"5e1fd1320a7d0b001275718a680f7c6d74343b40aecf9af5c16fd6a532144584"
);
}
result:
Xh/RMgp9CwASdXGKaA98bXQ0O0Cuz5r1wW/WpTIURYQ=
Thank you.