Периодическая (но частая) ошибка проверки Google Identity Toolkit: слишком большой открытый текст

Иногда, но не всегда, я получаю сообщение об ошибке от Google Identity Toolkit: «Открытый текст слишком велик». Кажется, он находится в разделе, когда он должен пытаться проверить подпись (с помощью RSA). Поскольку он проверяет хэш SHA256 полезной нагрузки, не должно быть никаких изменений в размере открытого текста.

Если я регистрирую токен, который он пытается использовать, и передаю его отладчику на странице https://jwt.io/, вместе с сертификатом Google RSA (из https://www.googleapis.com/identitytoolkit/v3/relyingparty/publicKeys; используйте идентификатор ключа, который jwt.io помещает в красное поле вверху под словом «ребенок»), он говорит, что подпись действительна.

Это случается только часть времени, может быть, чуть больше половины. Если я повторю аутентификацию, все будет в порядке.

Похоже, это происходит только при новых аутентификациях; если он уже аутентифицирован, все работает нормально, хотя я в настоящее время не использую cookie сеанса: мой код проверяет аутентификацию gtoken при каждом запросе. После входа в систему все в порядке, пока я не выйду (опять же, через gitkit). Но тогда, если я позже войду снова, я, скорее всего, столкнусь с этой ошибкой.

Я использую App Engine для своей инфраструктуры. Это происходит как с dev_appserver, так и с развернутым App Engine, а также с обоими настольными браузерами, использующими библиотеку JavaScript gitkit, и приложением iOS, использующим библиотеку gitkit Objective C. (Я не тестировал iOS на dev_appserver, только при развертывании.)

Код, который я использую, выглядит так:

    gtoken = cookie["gtoken"].value
    logging.debug("Verifying Google Identity Toolkit token: %s",
                  gtoken)
    gitkit_user = gitkit_instance.VerifyGitkitToken(gtoken)

Трассировка стека следует (начиная со строки, указанной выше):

  File "/base/data/home/apps/redacted/redacted.py", line 218, in redacted:
    gitkit_user = gitkit_instance.VerifyGitkitToken(gtoken)
  File "/base/data/home/apps/redacted/lib/identitytoolkit/gitkitclient.py", line 266, in VerifyGitkitToken
    parsed = crypt.verify_signed_jwt_with_certs(jwt, certs, aud)
  File "/base/data/home/apps/redacted/lib/oauth2client/crypt.py", line 240, in verify_signed_jwt_with_certs
    _verify_signature(message_to_sign, signature, certs.values())
  File "/base/data/home/apps/redacted/lib/oauth2client/crypt.py", line 119, in _verify_signature
    if verifier.verify(message, signature):
  File "/base/data/home/apps/redacted/lib/oauth2client/_pycrypto_crypt.py", line 52, in verify
    SHA256.new(message), signature)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/pycrypto-2.6/Crypto/Signature/PKCS1_v1_5.py", line 148, in verify
    m = self._key.encrypt(S, 0)[0]
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/pycrypto-2.6/Crypto/PublicKey/RSA.py", line 150, in encrypt
    return pubkey.pubkey.encrypt(self, plaintext, K)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/pycrypto-2.6/Crypto/PublicKey/pubkey.py", line 75, in encrypt
    ciphertext=self._encrypt(plaintext, K)
  File "/base/data/home/runtimes/python27/python27_lib/versions/third_party/pycrypto-2.6/Crypto/PublicKey/RSA.py", line 224, in _encrypt
    return (self.key._encrypt(c),)
ValueError: Plaintext too large

Ошибка «Слишком большой открытый текст» должна возникать только тогда, когда размер полезной нагрузки превышает размер ключа RSA. Поскольку он проверяет хэш SHA256 на 2048-битный ключ RSA, все должно быть в порядке, поэтому мне интересно, есть ли иногда проблема с загрузкой ключа с googleapis.com. Мой следующий шаг - использовать модуль статистики API для поиска вызовов urlfetch в запросах, где это происходит, и увеличить _pycrypto_crypt.py для регистрации того, какой ключ RSA он пытается проверить. Но я подумал, что проверю здесь, в Stack Overflow, и посмотрю, прошел ли кто-нибудь уже по этому пути.

Обновление: с некоторыми дополнительными записями я узнал несколько вещей. Во-первых, вместо использования идентификатора ключа, указанного в заголовках JWT, gitkit API (или одна из используемых им библиотек) повторяет попытки каждого ключа в наборе ключей Google Identity Toolkit. Во-вторых, когда я получал ошибку в то время, когда у меня было достаточное количество журналов, я тестировал один из ключей, который действительно находится в наборе ключей, так что это опровергает мою теорию о проблемах с загрузкой ключей. Но на самом деле он пытается сравнить 256-байтовую строку с 2048-битным ключом, так что все должно быть в порядке.

Наконец, хотя обычно он перебирает все ключи, когда я получаю эту ошибку, она попадает в ошибку на первом ключе, который пытается. Это заставляет меня задаться вопросом, не импортирую ли я сломанный pycrypto на ранней стадии в некоторых случаях.

Как видно из трассировки, я использую pycrypto, поставляемый Google, хотя в каталоге lib моего приложения (который находится в sys.path) есть локально скомпилированный, который был сохранен там, когда я продавал в Google Инструментарий идентификации.


person Piquan    schedule 20.03.2016    source источник
comment
У меня такая же проблема (с идентичными сообщениями об ошибках) .. есть ли обновления о том, где вы находитесь?   -  person Dennis    schedule 18.04.2016
comment
Испытывает ту же проблему. Вы нашли какое-нибудь решение?   -  person Sony Kadavan    schedule 20.05.2016
comment
@SonyKadavan Боюсь, что нет. Я добавил код в PyCryptoVerifier.verify и поместил туда блок try: catch. Теперь он будет возвращать False в случае ValueError вместо распространения ошибки. Вроде бы рабочий способ обхода, но меня это не устраивает.   -  person Piquan    schedule 22.05.2016


Ответы (1)


PyCrypto устарел и не рекомендуется для использования разработчиками.
Если вы используя GAE Standard, вы по-прежнему можете полагаться на собственный SSL Python.

Иногда я сталкивался с этой ошибкой. Как вы очень хорошо сказали, это связано с тем фактом, что PyCrypto выполняет итерацию по всем возможным ключам в наборе ключей, поэтому в зависимости от порядка вы можете нажать клавишу, достаточно большую, чтобы исчерпать ожидаемые ресурсы для нее, как указано в одна из проблем, связанных с этим.

Некоторое время работаю с ssl: 2.7.11 без проблем. Если вы хотите попробовать и у вас нет внутренней зависимости от pyCrypto, обновите свой app.yaml до:

 - name: ssl
   version: "2.7.11"
person Jose L Ugia    schedule 27.11.2017