简短版:如何使用Python使用Amazon CloudFront / S3使签名的URL“按需”以模仿Nginx的X-Accel-
Redirect行为(即保护下载)。
我已经安装了Django服务器,并在Nginx前端上运行。我一直对它的请求感到困惑,最近不得不将其安装为Tornado
WSGI应用程序,以防止它在FastCGI模式下崩溃。
现在由于服务器对媒体的请求过多,我的服务器陷入了瘫痪(即其大部分带宽已用尽)的问题,我一直在研究CDN,我相信Amazon CloudFront /
S3对我来说将是正确的解决方案。
我一直在使用Nginx的X-Accel-Redirect标头来保护文件免遭未经授权的下载,但是CloudFront /
S3-不具备这种功能,但是它们提供签名的URL。我到目前为止还不是Python专家,而且绝对不知道如何正确创建一个Signed
URL,所以我希望有人可以链接到如何“按需”设置这些URL,或者愿意解释如何在这里,将不胜感激。
另外,这是否是正确的解决方案?我对CDN不太熟悉,是否有CDN更适合于此?
Amazon
CloudFront签名URL
与Amazon
S3签名URL的工作方式不同。CloudFront使用基于单独的CloudFront密钥对的RSA签名,您必须在Amazon Account
Credentials页面中对其进行设置。这是一些代码,可以使用M2Crypto库在Python中实际生成一个限时URL
:
为CloudFront创建密钥对
我认为唯一的方法就是通过亚马逊的网站。进入您的AWS“账户”页面,然后单击“安全凭证”链接。单击“密钥对”选项卡,然后单击“创建新的密钥对”。这将为您生成一个新的密钥对,并自动下载一个私钥文件(pk-
xxxxxxxxx.pem)。确保密钥文件安全和私密。还要记下亚马逊的“密钥对ID”,因为下一步将需要它。
在Python中生成一些URL
从boto 2.0版开始,似乎不支持生成签名的CloudFront
URL。Python在标准库中不包含RSA加密例程,因此我们将不得不使用其他库。在此示例中,我使用了M2Crypto。
对于非流媒体分发,您必须使用完整的Cloudfront
URL作为资源,但是对于流媒体,我们仅使用视频文件的对象名称。有关生成仅持续5分钟的URL的完整示例,请参见下面的代码。
此代码大致基于Amazon在CloudFront文档中提供的PHP示例代码。
from M2Crypto import EVP
import base64
import time
def aws_url_base64_encode(msg):
msg_base64 = base64.b64encode(msg)
msg_base64 = msg_base64.replace('+', '-')
msg_base64 = msg_base64.replace('=', '_')
msg_base64 = msg_base64.replace('/', '~')
return msg_base64
def sign_string(message, priv_key_string):
key = EVP.load_key_string(priv_key_string)
key.reset_context(md='sha1')
key.sign_init()
key.sign_update(message)
signature = key.sign_final()
return signature
def create_url(url, encoded_signature, key_pair_id, expires):
signed_url = "%(url)s?Expires=%(expires)s&Signature=%(encoded_signature)s&Key-Pair-Id=%(key_pair_id)s" % {
'url':url,
'expires':expires,
'encoded_signature':encoded_signature,
'key_pair_id':key_pair_id,
}
return signed_url
def get_canned_policy_url(url, priv_key_string, key_pair_id, expires):
#we manually construct this policy string to ensure formatting matches signature
canned_policy = '{"Statement":[{"Resource":"%(url)s","Condition":{"DateLessThan":{"AWS:EpochTime":%(expires)s}}}]}' % {'url':url, 'expires':expires}
#sign the non-encoded policy
signature = sign_string(canned_policy, priv_key_string)
#now base64 encode the signature (URL safe as well)
encoded_signature = aws_url_base64_encode(signature)
#combine these into a full url
signed_url = create_url(url, encoded_signature, key_pair_id, expires);
return signed_url
def encode_query_param(resource):
enc = resource
enc = enc.replace('?', '%3F')
enc = enc.replace('=', '%3D')
enc = enc.replace('&', '%26')
return enc
#Set parameters for URL
key_pair_id = "APKAIAZVIO4BQ" #from the AWS accounts CloudFront tab
priv_key_file = "cloudfront-pk.pem" #your private keypair file
# Use the FULL URL for non-streaming:
resource = "http://34254534.cloudfront.net/video.mp4"
#resource = 'video.mp4' #your resource (just object name for streaming videos)
expires = int(time.time()) + 300 #5 min
#Create the signed URL
priv_key_string = open(priv_key_file).read()
signed_url = get_canned_policy_url(resource, priv_key_string, key_pair_id, expires)
print(signed_url)
#Flash player doesn't like query params so encode them if you're using a streaming distribution
#enc_url = encode_query_param(signed_url)
#print(enc_url)
确保您使用一个TrustedSigners参数设置您的分发,该参数设置为持有密钥对的帐户(如果是您自己的帐户,则为“ Self”)
除了签名url,Amazon最近还引入了Cloudfront签名cookie。 关于签名url也有类似的问题。显然,CloudFrontSDK中支持签名url 然而,我在aws python SDK中找不到对该功能的支持。
我试图使用以下工作流程创建PAdES签名: PDF准备签名,哈希在浏览器中计算 哈希发送到后端 后端形成分离的CAdES签名 分离的CAdES被发送回组装PAdES签名的浏览器 我们有一个PDF签名的工作示例,其工作原理如下: 准备好PDF,并在浏览器中计算哈希值 这很好用。 然而,现在我们在后端使用DSS库,而不是BouncyCastle,因为我们正在尝试创建PAdES签名。因此,DSS lib
是否可以使用存储在Azure密钥库中的X509证书创建RSA-SHA1签名?“不可抵赖证明书” 不幸的是,我不能将哈希算法更改为SHA256或更安全的东西,我真的需要将证书作为密钥存储在Azure Key Vault中。 null
数字签名允许我们验证签名的作者,日期和时间,验证消息内容。 它还包括用于其他功能的身份验证功能。 数字签名的优点 在本节中,我们将了解要求使用数字签名的不同原因。 将数字签名实施到通信有几个原因 - 身份验证 (Authentication) 数字签名有助于验证消息来源。 例如,如果银行的分支机构向中央办公室发送消息,请求更改帐户余额。 如果中央办公室无法验证从授权来源发送的消息,则执行此类请求可
我有所有的参数,像Key-id,cloudfront domain和pem文件。但我不知道如何实现它。谁能帮我拿些样品。 我找了很多,但没有找到。我得到了使用node.js创建签名url的示例代码,但我不想使用node.js。
我正在尝试为Google云存储中的私人存储文件创建签名;这样我就可以分发一个限时链接。 现在这样做,它的签名太短了...我哪里错了?