Apple发布了一种新的方法来对服务器到服务器的CloudKit进行身份验证.https://developer.apple.com/library/content/documentation/DataManagement/Conceptual/CloudKitWebServicesReference/SettingUpWebServices.html#//apple_ref/doc/uid/TP40015240-CH24-SW6
我尝试对CloudKit和此方法进行身份验证.起初我生成了密钥对并将公钥提供给CloudKit,到目前为止没问题.
我开始构建请求标头.根据文档,它应该如下所示:
X-Apple-CloudKit-Request-KeyID: [keyID]
X-Apple-CloudKit-Request-ISO8601Date: [date]
X-Apple-CloudKit-Request-SignatureV1: [signature]
Run Code Online (Sandbox Code Playgroud)
文件说:
在步骤1中创建的签名.
第1步说:
连接以下参数并用冒号分隔它们.
[Current date]:[Request body]:[Web Service URL]
我问自己"为什么我必须生成密钥对?".
但第2步说:
使用您的私钥计算此消息的ECDSA签名.
也许他们的意思是用私钥签名连接签名并将其放入标题?无论如何我试过两个......
我对此(无符号)签名值的示例如下所示:
2016-02-06T20:41:00Z:YTdkNzAwYTllNjI1M2EyZTllNDNiZjVmYjg0MWFhMGRiMTE2MjI1NTYwNTA2YzQyODc4MjUwNTQ0YTE5YTg4Yw==:https://api.apple-cloudkit.com/database/1/[iCloud Container]/development/public/records/lookup
Run Code Online (Sandbox Code Playgroud)
请求体值是SHA256哈希值,然后是base64编码的.我的问题是,我应该用":"连接,但是网址和日期也包含":".这是对的吗?(我还尝试对URL进行URL编码并删除日期中的":").
接下来,我用ECDSA签署了这个签名字符串,将其放入标题并发送.但我总是得到401"身份验证失败".为了签名,我使用ecdsa python模块,使用以下命令:
from ecdsa import SigningKey
a = SigningKey.from_pem(open("path_to_pem_file").read())
b = "[date]:[base64(request_body)]:/database/1/iCloud....."
print a.sign(b).encode('hex')
Run Code Online (Sandbox Code Playgroud)
也许python模块无法正常工作.但它可以从私钥生成正确的公钥.所以我希望其他功能也能奏效.
有没有人设法使用服务器到服务器方法对CloudKit进行身份验证?它是如何正常工作的?
编辑:正确的python版本工作
from ecdsa import SigningKey
import ecdsa, base64, hashlib
a = SigningKey.from_pem(open("path_to_pem_file").read())
b = "[date]:[base64(sha256(request_body))]:/database/1/iCloud....."
signature = a.sign(b, hashfunc=hashlib.sha256, sigencode=ecdsa.util.sigencode_der)
signature = base64.b64encode(signature)
print signature #include this into the header
Run Code Online (Sandbox Code Playgroud)