Unnable to create presigned url to download object from eu-west-3 - amazon-web-services

Im trying to create presigned urls to give download access to private files that live on an S3 bucket. I have 2 buckets, one on us-east-1 and the other on eu-west-3.
I've tried creating the presigned url with both AWS CLI and Python SDK (Boto 3) but didn't manage to get lucky when doing it on the EU bucket. On the us-east-1, i can do it with V2 and V4 signing.
The server always returns this response:
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>MYACCESSKEY</AWSAccessKeyId><StringToSign>AWS4-HMAC-SHA256
20190829T174117Z
20190829/eu-west-3/s3/aws4_request
e57ecda0a9ef1693b962d285c1748bd28284d2e2d069bceb44fad975e480b964</StringToSign><SignatureProvided>674e84fda296c6d0e14ff8dd6a02f9af92d08ed2f6556547c63cbd057603148f</SignatureProvided><StringToSignBytes></StringToSignBytes>
<CanonicalRequest>GET
/public/video.mp4
X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=MYACCESSKEY%2F20190829%2Feu-west-3%2Fs3%2Faws4_request&X-Amz-Date=20190829T174117Z&X-Amz-Expires=600&X-Amz-SignedHeaders=host
host:mybucket.s3.eu-west-3.amazonaws.com
host
UNSIGNED-PAYLOAD</CanonicalRequest>
<CanonicalRequestBytes>47 45 54 0a 2f 70 75 62 6c 69 63 2f 76 69 64 65 6f 2e 6d 70 34 0a 58 2d 41 6d 7a 2d 41 6c 67 6f 72 69 74 68 6d 3d 41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 26 58 2d 41 6d 7a 2d 43 72 65 64 65 6e 74 69 61 6c 3d 41 4b 49 41 5a 54 48 34 47 4b 4b 57 58 42 55 59 48 46 55 59 25 32 46 32 30 31 39 30 38 32 39 25 32 46 65 75 2d 77 65 73 74 2d 33 25 32 46 73 33 25 32 46 61 77 73 34 5f 72 65 71 75 65 73 74 26 58 2d 41 6d 7a 2d 44 61 74 65 3d 32 30 31 39 30 38 32 39 54 31 37 34 31 31 37 5a 26 58 2d 41 6d 7a 2d 45 78 70 69 72 65 73 3d 36 30 30 26 58 2d 41 6d 7a 2d 53 69 67 6e 65 64 48 65 61 64 65 72 73 3d 68 6f 73 74 0a 68 6f 73 74 3a 65 75 73 74 6f 72 65 2d 6d 6f 68 6f 2e 73 33 2e 65 75 2d 77 65 73 74 2d 33 2e 61 6d 61 7a 6f 6e 61 77 73 2e 63 6f 6d 0a 0a 68 6f 73 74 0a 55 4e 53 49 47 4e 45 44 2d 50 41 59 4c 4f 41 44</CanonicalRequestBytes>
<RequestId>496495C76B32097B</RequestId>
<HostId>Eue5AWLgtRWvivCE9ralzfc1ilUrLsnT+bWakSbeR5JYoSk1vbhYpwFxbeDbozJ7f1X1KLA5+Zc=</HostId></Error>
I obscured the bucket name and access key.
Here it is my python code: I'm using boto3-1.9.218 botocore-1.12.218 and Python 2.7.13.
import logging
import boto3
from botocore.exceptions import ClientError
import requests
from botocore.client import Config
'''
region = 'us-east-1'
tbucket = '<usbucket>'
'''
region = 'eu-west-3'
tbucket = '<eubucket>'
filekey = 'public/video.mp4'
s3 = boto3.client(
's3',
# Hard coded strings as credentials, not recommended.
aws_access_key_id='<access_key_id>',
aws_secret_access_key='<secret>',
config=Config(signature_version='s3v4'),
region_name=region
)
# This works
response = s3.list_buckets()
print('Existing buckets:')
for bucket in response['Buckets']:
print(bucket["Name"])
# this works
s3.download_file(tbucket, filekey, 'some video.mp4')
# this works
url = ""
try:
url = s3.generate_presigned_url('get_object', Params={ 'Bucket': tbucket, 'Key': filekey }, ExpiresIn=600)
except ClientError as e:
logging.error(e)
# Using the url does not work. Error 403
print(url)
if url is not None:
response = requests.get(url)
print(response)

Related

Google Deployment Manager stored runtime-config variables appear corrupted

I'm having trouble with encrypted base64 encoded values I'm using in Google Deployment Manager via runtimeconfig.v1beta1.config resource declarations.
After I perform the deployment, the value that I stored using Deployment Manager appear to be quite different to what I retrieve using gcloud beta runtime-configs. As a result, I can't decrypt the value.
First I encrypted and base64 encoded some secret text:
$ echo "secret"|gcloud kms encrypt --key my-crypto-key \
--keyring my-keyring --location australia-southeast1 \
--plaintext-file - --ciphertext-file - | base64 -w0
CiQAsOSNmVXBs2ayUjRePnE5+Oi5dUPuVvjn6UKKUXgxMTA56koSMABDkVUGnXlocFgdUEsQ5qLCF3PVIz5zit+ZCSXjSvNzEAO5XRv6WBRkxBJMjVcheg==
Which I then store in a deployment manager YAML file:
resources:
- name: my-config
type: runtimeconfig.v1beta1.config
properties:
config: my-config
description: "A demo configuration"
- name: dummy-secret
type: runtimeconfig.v1beta1.variable
properties:
parent: $(ref.my-config.name)
variable: 'dummy/secret'
value: "CiQAsOSNmVXBs2ayUjRePnE5+Oi5dUPuVvjn6UKKUXgxMTA56koSMABDkVUGnXlocFgdUEsQ5qLCF3PVIz5zit+ZCSXjSvNzEAO5XRv6WBRkxBJMjVcheg=="
Then I create the deployment (which completes without errors or warnings):
$ gcloud deployment-manager deployments create my-config \
--config my-config.yaml
But when I try extracting the variable value, it is completely different from what I stored:
$ gcloud beta runtime-config configs variables \
get-value 'dummy/secret' --config-name my-config|base64 -w0
CiQAPz8/P1U/P2Y/UjRePnE5Pz8/dUM/Vj8/P0I/UXgxMTA5P0oSMABDP1UGP3locFgdUEsQPz8/F3M/Iz5zPz8/CSU/Sj9zEAM/XRs/WBRkPxJMP1cheg==
This is repeatable / reproducible and I haven't a clue what I'm doing wrong. I don't have this problem using gcloud beta runtime-config variables set followed by get-value.
Looking at the decoded base64 binary of your content, we notice that all the bytes with values >= 0x80 have been changed to 0x3F, ASCII '?'. We suspect you're passing the binary data through the shell or some other pipe which isn't binary-clean.
Corrupted value:
dierks#dierks:~$ base64 -d | hexdump -C
CiQAPz8/P1U/P2Y/UjRePnE5Pz8/dUM/Vj8/P0I/UXgxMTA5P0oSMABDP1UGP3locFgdUEsQPz8/F3M/Iz5zPz8/CSU/Sj9zEAM/XRs/WBRkPxJMP1cheg==
00000000 0a 24 00 3f 3f 3f 3f 55 3f 3f 66 3f 52 34 5e 3e |.$.????U??f?R4^>|
00000010 71 39 3f 3f 3f 75 43 3f 56 3f 3f 3f 42 3f 51 78 |q9???uC?V???B?Qx|
00000020 31 31 30 39 3f 4a 12 30 00 43 3f 55 06 3f 79 68 |1109?J.0.C?U.?yh|
00000030 70 58 1d 50 4b 10 3f 3f 3f 17 73 3f 23 3e 73 3f |pX.PK.???.s?#>s?|
00000040 3f 3f 09 25 3f 4a 3f 73 10 03 3f 5d 1b 3f 58 14 |??.%?J?s..?].?X.|
00000050 64 3f 12 4c 3f 57 21 7a |d?.L?W!z|
00000058
Original value:
dierks#dierks:~$ base64 -d | hexdump -C
CiQAsOSNmVXBs2ayUjRePnE5+Oi5dUPuVvjn6UKKUXgxMTA56koSMABDkVUGnXlocFgdUEsQ5qLCF3PVIz5zit+ZCSXjSvNzEAO5XRv6WBRkxBJMjVcheg==
00000000 0a 24 00 b0 e4 8d 99 55 c1 b3 66 b2 52 34 5e 3e |.$.....U..f.R4^>|
00000010 71 39 f8 e8 b9 75 43 ee 56 f8 e7 e9 42 8a 51 78 |q9...uC.V...B.Qx|
00000020 31 31 30 39 ea 4a 12 30 00 43 91 55 06 9d 79 68 |1109.J.0.C.U..yh|
00000030 70 58 1d 50 4b 10 e6 a2 c2 17 73 d5 23 3e 73 8a |pX.PK.....s.#>s.|
00000040 df 99 09 25 e3 4a f3 73 10 03 b9 5d 1b fa 58 14 |...%.J.s...]..X.|
00000050 64 c4 12 4c 8d 57 21 7a |d..L.W!z|

Zlib inflate unexpected decompression errors

I am struggling for a few weeks with zlib inflate alghorithm.
I would like to decompress packets from popular game called Tibia. They have compressed it with zlib inflate alghorithms. But it seems something is changed. Can you check it, maybe you will spot something I am missing?
Packet compressed: - cannot be inflated directly (its raw huffman fixed coding - probably)
DA 22 A6 CB 10 99 5F AA 50 9C 9A AA 90 A8 90 05 B4 2F B5 44 41 C3 B1 28 D7 CA 50 53 8F CB B3 44 A1 3C 35 33 3D A3 58 C1 C8 44 CF C0 40 21 BF 4A 0F
Packet decompressed using Reverse Engineering:
B4 16 2D 00 59 6F 75 20 73 65 65 20 61 20 6A 61 63 6B 65 74 20 28 41 72 6D 3A 31 29 2E 0A 49 74 20 77 65 69 67 68 73 20 32 34 2E 30 30 20 6F 7A 2E
Decompressed packet compressed with zlib deflate using CyberChef deflate / php deflate functions:
db 22 a6 cb 10 99 5f aa 50 9c 9a aa 90 a8 90 95 98 9c 9d 5a a2 a0 e1 58 94 6b 65 a8 a9 c7 e5 59 a2 50 9e 9a 99 9e 51 ac 60 64 a2 67 60 a0 90 5f a5 07 00
Data matches in a few places, but generally, its different. Do you know what could be the case?
I attach a picture from RE an inflating function: Screenshot from IdaPro
Here are packets in correct order:
http://wklej.org/hash/6aee9e223f0/txt/ - inflated correctly
http://wklej.org/hash/bd371e7f510/txt/ - inflated correctly
http://wklej.org/hash/8f15935dc15/txt/ - inflated correctly
And here is the packet that cannot be inflated...
CA059BC6043619009FC9FFFFE831
Your packet that cannot be inflated is likely part of a longer stream of compressed data, with other packets preceding it and following it. You need to decompress all of them as a single stream for the decompression to succeed.
Your first example is a portion of a deflate stream that references data that preceded it. So it is part of a larger deflate stream. You need all of the compressed data that preceded that piece in order to decompress that piece. Your last example (CA05...) also references preceding data, so it too is part of a larger stream with compressed data that preceded it.

How is running the asset_management.go different from running a simple chaincode like chaincode_example02.go

The simple workflow for deploying/invoking a chaincode (to my knowledge) is :
Deploy a chaincode(smart contract) on the blockchain
This brings up a docker container on all peers that has the chaincode running in it
Invoke some function
This type of function changes the values of variables in chaincode state
For asset_management.go, the chaincode can be tested by running go test in the asset_management chaincode directory . But this does not really bring up a docker container(or does it ?) that runs the asset_management chaincode.
Whats the right way to deploy/invoke this chaincode and how is it different from deploying/invoking chaincodes using the REST interface(like we do for chaincode_example02)
The chaincode workflow you mentioned is correct, just one detail regarding variables in chaincode state: the variables are stored in a global key-value collection named World State, which is accessed through the invocation of a chaincode and it is access protected.
Now, what you are doing with go test is running the code in asset_management_test.go. If you look at this code, you will see that it basically starts a VP and a CA and then tries sending transactions to tests that the chaincode works. For example:
// Now create the Transactions message and send to Peer.
transaction, err := txHandler.NewChaincodeExecute(chaincodeInvocationSpec, tid)
You could also code a test file for the chaincode_example02 and test it.
Or you can also deploy the asset_management chaincode the same way you use to deploy chaincode_example02. Which can be using a chaincode development environment or a development network.
Important: asset_management chaincode is used to test the invocation access control, so it is fairly complex. Invoking its methods means using digital signatures to check the identity of the chaincode invoker. You can check the asset_management_test file to see how it is done.
The list of steps for anybody who would like to run “asset_management_with_roles” manually:
Checkout Fabric, run vagrant from “devenv” folder
ssh to the started container.
Reset Fabric’s configuration:
rm /var/hyperledger/production
Enable attribute certificate authority in membersrvc.yaml
aca.enabled: true
Enable security in core.yaml
security.enable: true
Switch log level for “node” to “debug” in core.yaml (optional. not necessary if you know the certificates)
logging.node: debug
Run membersrvc in background:
nohup membersrvc &> /tmp/membersrvc.log &
Run peer service
peer node start
Verify if users “assigner, bob, alice” are in membersrvc.yaml, according to the comment in this example we will work with:
// This example implements asset transfer using attributes support and specifically Attribute Based Access Control (ABAC).
// There are three users in this example:
// - alice
// - bob
// - assigner
//
// This users are defined in the section “eca" of asset.yaml file.
// In the section “aca" of asset.yaml file two attributes are defined to this users:
// The first attribute is called ‘role' with this values:
// - alice has role = client
// - bob has role = client
// - assigner has role = assigner
//
// The second attribute is called ‘account' with this values:
// - alice has account = 12345-56789
// - bob has account = 23456-67890
Open another ssh terminal with vagrant and login to the network:
peer network login assigner -p Tc43PeqBl11
peer network login bob -p NOE63pEQbL25
peer network login alice -p CMS10pEQlB16
8. Deploy chaincode to the network using “assigner” security context:
curl -XPOST -d ‘{“jsonrpc": "2.0", "method": "deploy", "params": {"type": 1,"chaincodeID": {"path": "github.com/hyperledger/fabric/examples/chaincode/go/asset_management_with_roles","language": "GOLANG"}, "ctorMsg": { "args": ["init"] }, "metadata":[97, 115, 115, 105, 103, 110, 101, 114] ,"secureContext": "assigner"} ,"id": 0}' http://localhost:7050/chaincode
metadata contains utf-8 encoded string “assigner”. This string will be saved in a ledger and only user with such role will be able to execute “assign” function in smart contract.
In order to keep example readable lets save chaincode id in local variable:
export HASH=7adc030881c07c39d2edac0b1560bf7cf2b7f0a4bce74fe7e6144e3f36e1bf2d176093d4c23ba58712a9589d9600e6d9ef596a1521a4c5227c222d8af2bf16c8
Starting from this moment user “assigner” can create new assets for bob and alice, we just have to find their certificates.
let’s run query command for any random asset name under “bob” securityContext:
curl -XPOST -d '{"jsonrpc": "2.0", "method": "query", "params": {"type": 1, "chaincodeID": {"name": "'"$HASH"'"}, "ctorMsg": {"args": ["query", "myasset"]}, "secureContext": "bob", "attributes": ["role", "account"]}, "id": 1}' http://localhost:7050/chaincode
(IMPORTANT: without “attributes”: [“role”, “account”] no attributes will be loaded into transactions certificate)
As far as “peer” is started in debug mode, bob’s certificate will be printed in peer log output. Try to find row “[client.bob] Adding new Cert” and copy certificate value:
30 82 02 90 30 82 02 37 a0 03 02 01 02 02 10 2f 9e 4e da c9 e9 4e 97 b1 58 24 78 4e 15 05 f4 30 0a 06 08 2a 86 48 ce 3d 04 03 03 30 31 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 14 30 12 06 03 55 04 0a 13 0b 48 79 70 65 72 6c 65 64 67 65 72 31 0c 30 0a 06 03 55 04 03 13 03 74 63 61 30 1e 17 0d 31 36 30 39 31 39 32 31 32 34 31 39 5a 17 0d 31 36 31 32 31 38 32 31 32 34 31 39 5a 30 45 31 0b 30 09 06 03 55 04 06 13 02 55 53 31 14 30 12 06 03 55 04 0a 13 0b 48 79 70 65 72 6c 65 64 67 65 72 31 20 30 1e 06 03 55 04 03 13 17 54 72 61 6e 73 61 63 74 69 6f 6e 20 43 65 72 74 69 66 69 63 61 74 65 30 59 30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a 86 48 ce 3d 03 01 07 03 42 00 04 78 8f f2 11 55 a3 5a 8d f1 b5 4f 38 e4 94 e4 67 b0 47 7f e0 07 04 b8 fb 12 ee 86 17 8a 05 55 e3 98 f6 c1 af 59 ee 2d 54 a9 c5 36 22 cd fa a8 1b ce ba e0 26 fd 73 40 af 20 5d 15 65 89 9c 62 64 a3 82 01 1b 30 82 01 17 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 07 80 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 0d 06 03 55 1d 0e 04 06 04 04 01 02 03 04 30 0f 06 03 55 1d 23 04 08 30 06 80 04 01 02 03 04 30 10 06 06 2a 03 04 05 06 0a 04 06 63 6c 69 65 6e 74 30 15 06 06 2a 03 04 05 06 0b 04 0b 32 33 34 35 36 2d 36 37 38 39 30 30 4d 06 06 2a 03 04 05 06 07 01 01 ff 04 40 fc c2 07 dd ee ac 8c 76 84 12 07 d2 e0 a6 da b3 06 c9 5b 5b 41 57 a3 f3 a2 f7 59 e2 ed 02 02 7e 56 46 f5 bc 24 00 0a 2e 18 b4 a6 b7 a6 c3 8d ca 15 13 a7 98 42 98 8f 9b 85 a2 d1 6a 77 0d da e8 30 3a 06 06 2a 03 04 05 06 08 04 30 ff d2 ab 7f c8 2d 98 c4 3f c9 f7 05 12 07 01 3a 36 69 f8 ee d1 c4 27 16 48 3e ee ed db b9 b6 3c d6 e5 1a 3e 0b 7d f0 19 1c 81 03 12 f6 7b d5 3e 30 23 06 06 2a 03 04 05 06 09 04 19 30 30 48 45 41 44 72 6f 6c 65 2d 3e 31 23 61 63 63 6f 75 6e 74 2d 3e 32 23 30 0a 06 08 2a 86 48 ce 3d 04 03 03 03 47 00 30 44 02 20 49 52 26 bd b8 f4 a0 98 c6 ff fc 56 3e b5 b0 12 ee ec b7 46 90 55 b1 17 99 29 fe df 80 2e 95 b9 02 20 3b 7f dd 32 88 56 ae a1 14 60 54 60 95 61 fb d1 bc 0c f7 e0 61 f2 e9 0b 46 35 6a 36 61 c9 b8 f0
Certificate should be based64 encoded. As an option we can use http://tomeko.net/online_tools/hex_to_base64.php?lang=en
Insert certificate into “Hex string” field, click “convert” button, and result will be in “Output (base64)”:
MIICkjCCAjigAwIBAgIRAO9nis6q+khvv6TMvhKbmacwCgYIKoZIzj0EAwMwMTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0h5cGVybGVkZ2VyMQwwCgYDVQQDEwN0Y2EwHhcNMTYwOTE5MjAyMDE5WhcNMTYxMjE4MjAyMDE5WjBFMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLSHlwZXJsZWRnZXIxIDAeBgNVBAMTF1RyYW5zYWN0aW9uIENlcnRpZmljYXRlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqop3N0IpJaLVaRuYioSuHPvyWX3OY9vo4I1YYw1YophcFGFt3fN0X6bDlufUZ5/u81JMmZHozduREnNzM1n+gaOCARswggEXMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMA0GA1UdDgQGBAQBAgMEMA8GA1UdIwQIMAaABAECAwQwEAYGKgMEBQYKBAZjbGllbnQwFQYGKgMEBQYLBAsyMzQ1Ni02Nzg5MDBNBgYqAwQFBgcBAf8EQNbPDmdWcOogMkZrlxbRJw/06jg4Ai88KW2+BsuxUnIH5FSa3OY7ZsXJLpceIN4SeEWKDKDsIPCo2wm6cUMYApIwOgYGKgMEBQYIBDDikSBKFYtTmYZRhtVDPhnIoSvefWHQ5Vx5oahIRbG8d/w4J1YTrtVoEwa2jikAqJowIwYGKgMEBQYJBBkwMEhFQURyb2xlLT4xI2FjY291bnQtPjIjMAoGCCqGSM49BAMDA0gAMEUCIQCrUQw2moOA5RFEx/780so4uEOV5esX3fy/It0t2la7gQIgGGVoDoM2kSxWH7TtV4T8W4pY6tN/LXu8XpKWb8+eF0k=
"assign" method expects 2 parameters the Name for asset and owner certificate. New asset can be created using:
curl -XPOST -d '{"jsonrpc": "2.0", "method": "invoke", "params": {"type": 1, "chaincodeID": {"name": "'"$HASH"'"}, "ctorMsg": {"args": ["assign", "myasset", "MIICkjCCAjigAwIBAgIRAO9nis6q+khvv6TMvhKbmacwCgYIKoZIzj0EAwMwMTELMAkGA1UEBhMCVVMxFDASBgNVBAoTC0h5cGVybGVkZ2VyMQwwCgYDVQQDEwN0Y2EwHhcNMTYwOTE5MjAyMDE5WhcNMTYxMjE4MjAyMDE5WjBFMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLSHlwZXJsZWRnZXIxIDAeBgNVBAMTF1RyYW5zYWN0aW9uIENlcnRpZmljYXRlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqop3N0IpJaLVaRuYioSuHPvyWX3OY9vo4I1YYw1YophcFGFt3fN0X6bDlufUZ5/u81JMmZHozduREnNzM1n+gaOCARswggEXMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMA0GA1UdDgQGBAQBAgMEMA8GA1UdIwQIMAaABAECAwQwEAYGKgMEBQYKBAZjbGllbnQwFQYGKgMEBQYLBAsyMzQ1Ni02Nzg5MDBNBgYqAwQFBgcBAf8EQNbPDmdWcOogMkZrlxbRJw/06jg4Ai88KW2+BsuxUnIH5FSa3OY7ZsXJLpceIN4SeEWKDKDsIPCo2wm6cUMYApIwOgYGKgMEBQYIBDDikSBKFYtTmYZRhtVDPhnIoSvefWHQ5Vx5oahIRbG8d/w4J1YTrtVoEwa2jikAqJowIwYGKgMEBQYJBBkwMEhFQURyb2xlLT4xI2FjY291bnQtPjIjMAoGCCqGSM49BAMDA0gAMEUCIQCrUQw2moOA5RFEx/780so4uEOV5esX3fy/It0t2la7gQIgGGVoDoM2kSxWH7TtV4T8W4pY6tN/LXu8XpKWb8+eF0k="]}, "metadata":[97, 115, 115, 105, 103, 110, 101, 114], "secureContext": "assigner", "attributes": ["role", "account"]}, "id": 1}' http://localhost:7050/chaincode
Try to run the query from step 9 for bob again:
curl -XPOST -d ‘{"jsonrpc": "2.0", "method": "query", "params": {"type": 1, "chaincodeID": {"name": "'"$HASH"'"}, "ctorMsg": {"args": ["query", "myasset"]}, "secureContext": "bob", "attributes": ["role", "account"]}, "id": 1}' http://localhost:7050/chaincode
and you will see that “myasset” is already created, and belongs to account “23456-67890”
Using the same approach we can find certificate for alice and change the owner for “myasset”.

SignatureDoesNotMatch responding to CustomResource using AWS CloudFormation

I've implemented a very basic CustomResource where I'm receiving the notification through SNS to an HTTPS subscriber without any problems. If I take the ResponseURL sent with the CustomResource notification and try to respond with a SUCCESS response, I continually get a 403-FORBIDDEN response from AWS using the pre-signed URL with a SignatureDoesNotMatch error code.
Through all my research and reviewing the aws-cfn-resource-bridge, there are two things that stand out.
The response is a PUT, good... easy enough.
The Content-Type HTTP header is set to a blank/empty string, alright... no problem there either although it doesn't make much sense.
Here is my request
PUT https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A741849072915%3Astack/scott-test/7181a360-50cc-11e5-8aae-5001b491380a%7CCloudFlareDNSRegistration%7C047ca252-bf0e-4fa7-a7ac-be97fc897095?AWSAccessKeyId=REMOVED&Expires=1441240852&Signature=yzmop7aF5TxOFjAG%2F7TvTpoZDS0%3D
Content-Type:
Content-Length: 305
{"Status":"SUCCESS","PhysicalResourceId":"scott-test- CloudFlareDNSRegistration-1KQIGCB3BP1AW","StackId":"arn:aws:cloudformation:us-east-1:741849072915:stack/scott-test/7181a360-50cc-11e5-8aae-5001b491380a","RequestId":"047ca252-bf0e-4fa7-a7ac-be97fc897095","LogicalResourceId":"CloudFlareDNSRegistration"}
The response I get:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>REMOVED</AWSAccessKeyId><StringToSign>PUT
1441240852
/cloudformation-custom-resource-response-useast1/arn%253Aaws%253Acloudformation%253Aus-east-1%253A741849072915%253Astack/scott-test/7181a360-50cc-11e5-8aae-5001b491380a%257CCloudFlareDNSRegistration%257C047ca252-bf0e-4fa7-a7ac-be97fc897095</StringToSign> <SignatureProvided>yzmop7aF5TxOFjAG%2F7TvTpoZDS0%3D</SignatureProvided> <StringToSignBytes>50 55 54 0a 0a 0a 31 34 34 31 32 34 30 38 35 32 0a 2f 63 6c 6f 75 64 66 6f 72 6d 61 74 69 6f 6e 2d 63 75 73 74 6f 6d 2d 72 65 73 6f 75 72 63 65 2d 72 65 73 70 6f 6e 73 65 2d 75 73 65 61 73 74 31 2f 61 72 6e 25 32 35 33 41 61 77 73 25 32 35 33 41 63 6c 6f 75 64 66 6f 72 6d 61 74 69 6f 6e 25 32 35 33 41 75 73 2d 65 61 73 74 2d 31 25 32 35 33 41 37 34 31 38 34 39 30 37 32 39 31 35 25 32 35 33 41 73 74 61 63 6b 2f 73 63 6f 74 74 2d 74 65 73 74 2f 37 31 38 31 61 33 36 30 2d 35 30 63 63 2d 31 31 65 35 2d 38 61 61 65 2d 35 30 30 31 62 34 39 31 33 38 30 61 25 32 35 37 43 43 6c 6f 75 64 46 6c 61 72 65 44 4e 53 52 65 67 69 73 74 72 61 74 69 6f 6e 25 32 35 37 43 30 34 37 63 61 32 35 32 2d 62 66 30 65 2d 34 66 61 37 2d 61 37 61 63 2d 62 65 39 37 66 63 38 39 37 30 39 35</StringToSignBytes><RequestId>EBFDA09E56D8313F</RequestId><HostId>MP66HkmQeXXH05wE2AQR4pWc99JFyCXJMfMSQk4xxbxSRj5qQJB7vAm7/dJH+rH4</HostId></Error>
I've found various questions where it was suggested the path needed to be decoded (i.e. altering the %3A to :) before making the request, I tried that with no luck. I'm using the URL provided as is in the ResponseURL field, doesn't seem like I should be altering it.
Any thoughts?
Through trial and error I was able to get the signatures to match. The details are to long to post unfortunately, but my original attempt was leveraging Spring's RestTemplate, where I attempted to get the headers correctly set for AWS. I switched to a straight Http Components HttpClient approach where I had more control of the actual HTTP request headers and body.

Access file using pre-signed url

I am adding an object to a bucket in Amazon S3. The addition is successful, now I want to make the file accessible to others by the pre-signed url.
The pre-signed url is of the form:
https://<bucket>.s3.amazonaws.com/<key>?AWSAccessKeyId=<access key>&Expires=1432722343&Signature=mmfv%2Fddhhakla1csUrb%2FtRCXYu8%3D
But when I try to load the url, it return with an error:
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your key and signing method.
</Message>
<AWSAccessKeyId></AWSAccessKeyId>
<StringToSign>
GET 1432727995 /<bucket>/<key>
</StringToSign>
<SignatureProvided>mmfv/ddhhakla1csUrb/tRCXYu8=</SignatureProvided>
<StringToSignBytes>
47 45 54 0a 0a 0a 31 34 33 32 37 32 37 39 39 35 0a 2f 72 69 2d 73 65 72 76 69 63 65 2d 74 72 61 6b 2d 74 65 73 74 2f 74 65 73 74 53 75 6e 69 74 31 2e 78 6d 6c
</StringToSignBytes>
<RequestId>0E72b9858758353A0D906</RequestId>
<HostId>
SOME VALUE
</HostId>
</Error>
Another Question:
If I have an URI that has '+' in it, how do I access the page using the URI because trying the URI in the web browser turns it into space(" ") and that isn't correct?