如何在服务器端使用Python生成签名URL?

0 投票
2 回答
3005 浏览
提问于 2025-04-18 12:49

我刚刚按照这个链接 https://developers.google.com/storage/docs/accesscontrol?hl=zh-TW#Signed-URLs 的说明,使用 gsutil 生成了签名网址,效果很好。

但是我想问的是“如何在服务器端生成签名网址?”

上面的云存储链接提到了一个示例项目 https://github.com/GoogleCloudPlatform/storage-signedurls-python

这个项目适合在 App Engine 环境中使用吗?如果可以的话,私钥文件应该放在哪里呢?

或者有没有更好的方法来解决这个问题?

2 个回答

0

下面是我们让它工作的步骤:

第一步:获取 p12 文件/证书

https://console.developers.google.com/ 下载 p12 文件,去“APIs & auth / Credentials”这个标签页。

第二步:将 p12 文件转换为 DER 格式

找到一台 Linux 电脑,打开终端并连接。

命令如下:

openssl pkcs12 -in <filename.p12> -nodes -nocerts > <filename.pem>
# The current Google password for the p12 file is `notasecret`

openssl rsa -in <filename.pem> -inform PEM -out <filename.der> -outform DER

第三步:将 DER 文件转换为 base64 编码字符串

在 Python 控制台中执行:

private_key = open(‘<filename.der>’, 'rb').read()
print private_key.encode('base64')

然后把结果复制粘贴到应用引擎的脚本里。

第四步:在 AppEngine 中启用 PyCrypto

在 app.yaml 文件中必须添加一行来启用 PyCrypto:

- name: pycrypto
  version: latest

第五步:用 Python 代码创建签名 URL

import Crypto.Hash.SHA256 as SHA256
import Crypto.PublicKey.RSA as RSA
import Crypto.Signature.PKCS1_v1_5 as PKCS1_v1_5

der_key = “””<copy-paste-the-base64-converted-key>”””.decode('base64')

bucket = <your cloud storage bucket name (default is same as app id)>
filename = <path + filename>

valid_seconds = 5
expiration = int(time.time() + valid_seconds)

signature_string = 'GET\n\n\n%s\n' % expiration
signature_string += bucket + filename



# Sign the string with the RSA key.
signature = ''
try:
  start_key_time = datetime.datetime.utcnow()
  rsa_key = RSA.importKey(der_key, passphrase='notasecret')
  #objects['rsa_key'] = rsa_key.exportKey('PEM').encode('base64')
  signer = PKCS1_v1_5.new(rsa_key)
  signature_hash = SHA256.new(signature_string)
  signature_bytes = signer.sign(signature_hash)
  signature = signature_bytes.encode('base64')

  objects['sig'] = signature
except:
  objects['PEM_error'] = traceback.format_exc()

try:
  # Storage
  STORAGE_CLIENT_EMAIL = <Client Email from Credentials console: Service Account Email Address>
  STORAGE_API_ENDPOINT = 'https://storage.googleapis.com'

  # Set the query parameters.
  query_params = {'GoogleAccessId': STORAGE_CLIENT_EMAIL,
                'Expires': str(expiration),
                'Signature': signature}


  # This is the signed URL:
  download_href = STORAGE_API_ENDPOINT + bucket + filename + '?' + urllib.urlencode(query_params)

except:
  pass

参考资料

如何获取 p12 文件。

签名的说明。

如何签名 URL 的灵感来源。

0

如果你在使用Python,有一个示例应用程序可以生成签名的链接,叫做 storage-signedurls-python

撰写回答