· 7 years ago · Jul 25, 2018, 02:40 PM
1def _sign(key, msg):
2 return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()
3
4def getV4Signature(date_stamp, regionName, policy):
5 kDate = _sign(('AWS4' + AWS_SECRET_KEY).encode('utf-8'), date_stamp)
6 kRegion = _sign(kDate, regionName)
7 kService = _sign(kRegion, 's3')
8 kSigning = _sign(kService, 'aws4_request')
9 kSignature = _sign(kSigning, policy)
10 return binascii.hexlify(kSignature)
11
12<script type="text/javascript">
13 // execute the code after the document is loaded
14 document.addEventListener("DOMContentLoaded", function() {
15 // The code
16 (function() {
17 var uploader = new qq.s3.FineUploader({
18 debug: true,
19 element: document.getElementById('fine-uploader'),
20 cors: {
21 expected: true
22 },
23 objectProperties: {
24 bucket: '<your bucket>',
25 region: 'cn-north-1',
26 acl: 'private',
27 key: "uuid",
28 },
29 request: {
30 endpoint: 'https://<your bucket>.s3.cn-north-1.amazonaws.com.cn',
31 accessKey: '<your public access key>',
32
33 },
34 signature: {
35 endpoint: '{{ url_for('data.s3_signature') }}',
36 version: 4,
37 customHeaders: {
38 "X-CSRF-Token": $("meta[name='csrf-token']").attr("content")
39 }
40 },
41 uploadSuccess: {
42 endpoint: '{{ url_for('data.s3_success') }}'
43 },
44 iframeSupport: {
45 localBlankPagePath: '/success.html'
46 },
47 chunking: {
48 enabled: true,
49 concurrent: {
50 enabled: true
51 }
52 },
53 resume: {
54 enabled: true
55 },
56 retry: {
57 enableAuto: true // defaults to false
58 },
59 deleteFile: {
60 enabled: true,
61 endpoint: '{{ url_for('data.s3_delete', key=key) }}'
62 }
63 })
64 }());
65 });
66 </script>
67
68def hash_sha256(msg:str):
69 """
70 Generate a SHA256 hash and return the base16 Uicode string.
71
72 msg -- A Unicode message to hash.
73
74 """
75 return binascii.hexlify(hashlib.sha256(
76 bytearray(msg.strip(), 'utf-8')).digest()).decode('utf-8')
77
78def sign_sha256(key, msg):
79 """
80 Generate an SHA256 HMAC, encoding msg to UTF-8 if not
81 already encoded.
82
83 key -- signing key. bytes.
84 msg -- message to sign. unicode or bytes.
85
86 """
87 if isinstance(msg, text_type):
88 msg = msg.encode('utf-8')
89 return hmac.new(key, msg, hashlib.sha256).digest()
90
91def generate_key(cls, secret_key, region, service, date,
92 intermediates=False):
93 """
94 Generate the signing key string as bytes.
95
96 If intermediate is set to True, returns a 4-tuple containing the key
97 and the intermediate keys:
98
99 ( signing_key, date_key, region_key, service_key )
100
101 The intermediate keys can be used for testing against examples from
102 Amazon.
103
104 """
105 init_key = ('AWS4' + secret_key).encode('utf-8')
106 date_key = cls.sign_sha256(init_key, date)
107 region_key = cls.sign_sha256(date_key, region)
108 service_key = cls.sign_sha256(region_key, service)
109 key = cls.sign_sha256(service_key, 'aws4_request')
110 if intermediates:
111 return (key, date_key, region_key, service_key)
112 else:
113 return key
114
115def sign_headers(headers):
116 """ Sign and return the headers for a chunked upload.
117 The headers sent from fineupload have the majority of what is needed. But
118 you must follow the process laid out in amazon docs to finish it.
119
120 https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
121 """
122 # cut the first three lines from the headers from fine uploader and sign the remaining as hashed_canonical_request
123 canonical_request = headers[70:]
124 # split the headers so you can build the string_to_sign
125 split_headers = headers.splitlines()
126 # grab the date from the header
127 yyyymmdd = split_headers[2][:8]
128 # hash the canonical request and then return the base16 string
129 hashed_canonical_request = hash_sha256(canonical_request)
130 # build the string_to_sign
131 string_to_sign = split_headers[0] + 'n' + split_headers[1] + 'n' + split_headers[2] + 'n' + hashed_canonical_request
132 # create the signing key
133 signing_key = generate_key(AWS_CLIENT_SECRET_KEY, S3_REGION_NAME, 's3', yyyymmdd)
134 # create the signature using the signing_key and string_to_sign
135 signature = sign_sha256(signing_key, string_to_sign)
136
137 return {
138 'signature': binascii.hexlify(signature).decode("utf-8")
139 }
140
141<?xml version="1.0" encoding="UTF-8"?>
142<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>[your public key]</AWSAccessKeyId><StringToSign>AWS4-HMAC-SHA256
14320180725T101212Z
14420180725/cn-north-1/s3/aws4_request
145e7a7e92e17d8a3ac6228bb02139a499904db50a493ea6c336d847d4d94a5c320</StringToSign><SignatureProvided>2afc0bc1316732c9cd9bdc75c0aafdde70c3c96c0211991c610cf0c1bed33d71</SignatureProvided><StringToSignBytes>41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 31 38 30 37 32 35 54 31 30 31 32 31 32 5a 0a 32 30 31 38 30 37 32 35 2f 63 6e 2d 6e 6f 72 74 68 2d 31 2f 73 33 2f 61 77 73 34 5f 72 65 71 75 65 73 74 0a 65 37 61 37 65 39 32 65 31 37 64 38 61 33 61 63 36 32 32 38 62 62 30 32 31 33 39 61 34 39 39 39 30 34 64 62 35 30 61 34 39 33 65 61 36 63 33 33 36 64 38 34 37 64 34 64 39 34 61 35 63 33 32 30</StringToSignBytes><CanonicalRequest>
146POST
147/39f0808e-3d0b-48d4-a3db-f171a3cb2943.mp4
148uploads=
149host:<your bucket>.s3.cn-north-1.amazonaws.com.cn
150x-amz-acl:private
151x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
152x-amz-date:20180725T101212Z
153x-amz-meta-qqfilename:flux-field_pro_854x480p.mp4
154
155host;x-amz-acl;x-amz-content-sha256;x-amz-date;x-amz-meta-qqfilename
156e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855</CanonicalRequest><CanonicalRequestBytes>50 4f 53 54 0a 2f 33 39 66 30 38 30 38 65 2d 33 64 30 62 2d 34 38 64 34 2d 61 33 64 62 2d 66 31 37 31 61 33 63 62 32 39 34 33 2e 6d 70 34 0a 75 70 6c 6f 61 64 73 3d 0a 68 6f 73 74 3a 61 6f 62 71 2e 73 33 2e 63 6e 2d 6e 6f 72 74 68 2d 31 2e 61 6d 61 7a 6f 6e 61 77 73 2e 63 6f 6d 2e 63 6e 0a 78 2d 61 6d 7a 2d 61 63 6c 3a 70 72 69 76 61 74 65 0a 78 2d 61 6d 7a 2d 63 6f 6e 74 65 6e 74 2d 73 68 61 32 35 36 3a 65 33 62 30 63 34 34 32 39 38 66 63 31 63 31 34 39 61 66 62 66 34 63 38 39 39 36 66 62 39 32 34 32 37 61 65 34 31 65 34 36 34 39 62 39 33 34 63 61 34 39 35 39 39 31 62 37 38 35 32 62 38 35 35 0a 78 2d 61 6d 7a 2d 64 61 74 65 3a 32 30 31 38 30 37 32 35 54 31 30 31 32 31 32 5a 0a 78 2d 61 6d 7a 2d 6d 65 74 61 2d 71 71 66 69 6c 65 6e 61 6d 65 3a 66 6c 75 78 2d 66 69 65 6c 64 5f 70 72 6f 5f 38 35 34 78 34 38 30 70 2e 6d 70 34 0a 0a 68 6f 73 74 3b 78 2d 61 6d 7a 2d 61 63 6c 3b 78 2d 61 6d 7a 2d 63 6f 6e 74 65 6e 74 2d 73 68 61 32 35 36 3b 78 2d 61 6d 7a 2d 64 61 74 65 3b 78 2d 61 6d 7a 2d 6d 65 74 61 2d 71 71 66 69 6c 65 6e 61 6d 65 0a 65 33 62 30 63 34 34 32 39 38 66 63 31 63 31 34 39 61 66 62 66 34 63 38 39 39 36 66 62 39 32 34 32 37 61 65 34 31 65 34 36 34 39 62 39 33 34 63 61 34 39 35 39 39 31 62 37 38 35 32 62 38 35 35</CanonicalRequestBytes><RequestId>056AA9A01FBFF8FB</RequestId><HostId>RzQYHes10dAU3rrnhyDRRwN4NzuNxn3JrVcjlfK8NEqagFh0DZ0gkT56bMrYNwDTcU2iuZQohaY=</HostId></Error>