sign_blob 使用方法
我想给一些数据(叫做blob)签名,然后把这个签名发回给用户。用户该怎么验证这个签名呢?如果能有个例子,教我怎么获取公钥证书和处理这个签名就好了。
2 个回答
1
这个问题虽然是个老问题,但我还是觉得很难找到具体的例子来说明怎么做!所以我把我的解决方案发出来,希望能帮到其他想知道怎么验证sign_blog
签名的人。搞笑的是,谷歌的Python页面居然没有任何例子。
这里有一个例子,展示了如何对一个数据块进行签名并验证它的签名:
但是没有任何示例。
我到处搜索后,终于在这个页面找到了一个例子。这个代码的作者是这样进行签名的:
from google.appengine.api import app_identity
def sign_blob(blob):
"""Signs a blob using current service's private key.
Uses GAE app_identity.sign_blob function. It has a limit of 8KB on a size of
a blob, so |blob| is hashed first (with sha512). So final signature is
RSA+SHA256(sha512(blob)).
Returns:
Tuple (name of a key used, signature).
"""
# app_identity.sign_blob is producing RSA+SHA256 signature. Sadly, it isn't
# documented anywhere. But it should be relatively stable since this API is
# used by OAuth2 libraries (and so changing signature method may break a lot
# of stuff).
return app_identity.sign_blob(hashlib.sha512(blob).digest())
同一个作者还使用了pycrypto
来进行验证。这个函数叫做check_signature
,在页面的底部。它工作得很好,但pycrypto
看起来并没有在积极更新。
我自己想出的一个实现使用了cryptography
库,这个库还在积极开发中。可以看看:
import base64
from google.appengine.api import app_identity
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.x509 import load_pem_x509_certificate
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.exceptions import InvalidSignature
def verify_signature(key_name, signature, data):
# Decode the signature
try:
signature = base64.b64decode(signature)
except TypeError:
return False
# Get the list of certificates app engine has been using
certs = app_identity.get_public_certificates()
# Match the key with a certificate
x509_cert_pem = None
for cert in certs:
if cert.key_name == key_name:
x509_cert_pem = cert.x509_certificate_pem
break
# Check that a certifcate matched
if not x509_cert_pem:
return False
# Create x509 cert object
x509_cert = load_pem_x509_certificate(x509_cert_pem, backend=default_backend())
# Extract the public key
public_key = x509_cert.public_key()
# Prep the verifier
verifier = public_key.verifier(
signature,
padding.PKCS1v15(),
hashes.SHA256()
)
verifier.update(data)
# No return value documented. Raises an error on mismatch
# https://cryptography.io/en/latest/hazmat/primitives/asymmetric/interfaces/#cryptography.hazmat.primitives.asymmetric.AsymmetricVerificationContext.verify # noqa
try:
result = verifier.verify()
except InvalidSignature:
return False
return (result is None)