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]
- [keyID], без проблем. Вы можете найти это в панели CloudKit.
- [Дата], я думаю, что это должно сработать: 2016-02-06T20: 41: 00Z
- [подпись], вот проблема...
В документации написано:
Подпись, созданная на шаге 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
Значение тела запроса SHA256 хэшируется и после этого кодируется base64. Мой вопрос: я должен конкатенировать с ":" , но в URL и в дате также содержится ":" . Правильно ли это? (Я также пытался 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')
Возможно, модуль python работает неправильно. Но он может генерировать правильный открытый ключ из закрытого ключа. Поэтому я надеюсь, что другие функции также будут работать.
Кто-нибудь смог пройти аутентификацию против CloudKit с помощью метода server-to-server? Как это работает правильно?
Изменить: Исправить версию 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