Created
March 28, 2015 03:11
-
-
Save trevorrowe/49bfb9d59f83ad450a9e to your computer and use it in GitHub Desktop.
Demonstration of using pre-signed GET url to download a server-side-encrypted with customer key from Amazon S3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'aws-sdk' | |
require 'openssl' | |
bucket_name = 'bucket-name' | |
object_key = 'object-key' | |
# patch for `aws-sdk` v2 gem (needed for versions <= v2.0.33, patch will be applied shortly to master) | |
class Aws::Signers::V4 | |
def presigned_url(request, options = {}) | |
now = Time.now.utc.strftime("%Y%m%dT%H%M%SZ") | |
body_digest = options[:body_digest] || hexdigest(request.body) | |
request.headers.delete('User-Agent') | |
request.headers['Host'] = request.endpoint.host | |
params = Aws::Query::ParamList.new | |
params.set("X-Amz-Algorithm", "AWS4-HMAC-SHA256") | |
params.set("X-Amz-Credential", credential(now)) | |
params.set("X-Amz-Date", now) | |
params.set("X-Amz-Expires", options[:expires_in].to_s) | |
params.set("X-Amz-SignedHeaders", signed_headers(request)) | |
params.set('X-Amz-Security-Token', credentials.session_token) if | |
credentials.session_token | |
endpoint = request.endpoint | |
if endpoint.query | |
endpoint.query += '&' + params.to_s | |
else | |
endpoint.query = params.to_s | |
end | |
endpoint.to_s + '&X-Amz-Signature=' + signature(request, now, body_digest) | |
end | |
end | |
# my "customer-provided-key" | |
cpk = OpenSSL::Cipher::AES.new(256, :CBC).random_key | |
# upload an object using Server-Side-Encryption with customer provided key | |
obj = Aws::S3::Object.new(bucket_name, object_key) | |
obj.put( | |
body: 'Hello World!', | |
sse_customer_algorithm: 'AES256', | |
sse_customer_key: cpk) | |
# download the object using the `aws-sdk` | |
obj.get(sse_customer_algorithm: 'AES256', sse_customer_key: cpk).body.read | |
#=> 'Hello World!' | |
# generate a presigned url | |
url = obj.presigned_url(:get, | |
sse_customer_algorithm: 'AES256', | |
sse_customer_key: cpk) | |
# use Ruby Net::HTTP to GET the encrypted object | |
uri = URI.parse(url) | |
http = Net::HTTP.new(uri.host, uri.port) | |
http.use_ssl = true | |
request = Net::HTTP::Get.new(uri.request_uri, { | |
"x-amz-server-side-encryption-customer-algorithm" => 'AES256', | |
"x-amz-server-side-encryption-customer-key" => Base64.encode64(cpk), | |
"x-amz-server-side-encryption-customer-key-MD5" => Base64.encode64(OpenSSL::Digest::MD5.digest(cpk)) | |
}) | |
resp = http.request(request) | |
puts resp.body | |
#=> Hello World! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment