Cloudfront vs S3签名URL和Boto3

时间:2017-06-18 07:49:59

标签: python amazon-web-services amazon-s3 amazon-cloudfront boto3

尝试设置完全签名和保护的云端URL。 例如。我想要一个应用程序代码来访问资源。

使用S3直接分发,我可以简单地使用:

s3 = boto3.client('s3')    
s3.generate_presigned_url('get_object', Params={'Bucket': bucket, 'Key': unique_key}, ExpiresIn=186400)

但我似乎无法弄清楚在请求云端网址时如何创建等效的签名网址。

2 个答案:

答案 0 :(得分:6)

boto3文档中有一节显示Generate a signed URL for Amazon CloudFront

  

以下示例显示如何为Amazon CloudFront生成签名URL。请注意,您需要使用加密库来遵循此示例:

import datetime

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from botocore.signers import CloudFrontSigner
def rsa_signer(message):
    with open('path/to/key.pem', 'rb') as key_file:
        private_key = serialization.load_pem_private_key(
            key_file.read(),
            password=None,
            backend=default_backend()
        )
    signer = private_key.signer(padding.PKCS1v15(), hashes.SHA1())
    signer.update(message)
    return signer.finalize()

key_id = 'AKIAIOSFODNN7EXAMPLE'
url = 'http://d2949o5mkkp72v.cloudfront.net/hello.txt'
expire_date = datetime.datetime(2017, 1, 1)

cloudfront_signer = CloudFrontSigner(key_id, rsa_signer)

# Create a signed url that will be valid until the specfic expiry date
# provided using a canned policy.
signed_url = cloudfront_signer.generate_presigned_url(
    url, date_less_than=expire_date)
print(signed_url)

Cloudfront vs S3

您会注意到上述代码使用公钥/私钥对来创建CloudFront签名URL。这意味着只要知道密钥对,任何应用程序都可以生成签名URL。

这与在Amazon S3中创建签名URL不同,后者使用属于生成请求的用户的密钥来验证请求。

为什么他们不一样?我不知道,但是keypair选项允许使用CloudFront而不需要任何IAM用户,这对仅使用CloudFront的客户可能很有用。但这只是猜测。

答案 1 :(得分:0)

对于那些发现此错误并看到来自Python加密模块的警告消息的人,请更新John的精彩回答。不推荐使用signer,而推荐使用序列化对象上的sign函数根据文档。

import datetime

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from botocore.signers import CloudFrontSigner
def rsa_signer(message):
   with open('path/to/key.pem', 'rb') as key_file:
       private_key = serialization.load_pem_private_key(
           key_file.read(),
           password=None,
           backend=default_backend()
       )
   return private_key.sign(message, padding.PKCS1v15(), hashes.SHA1())

key_id = 'AKIAIOSFODNN7EXAMPLE'
url = 'http://d2949o5mkkp72v.cloudfront.net/hello.txt'
expire_date = datetime.datetime(2017, 1, 1)

cloudfront_signer = CloudFrontSigner(key_id, rsa_signer)

# Create a signed url that will be valid until the specfic expiry date
# provided using a canned policy.
signed_url = cloudfront_signer.generate_presigned_url(
     url, date_less_than=expire_date)
print(signed_url)

这只会更新答案,因此不会引发弃用警告,也不会关注所使用部件的安全性。