Вы не опубликовали свой код в своем вопросе, поэтому я не знаю, как вы создаете JWT для подписи.
[ПРАВИТЬ 1/18/2019 после добавления кода к вопросу]
Ваш код делает подпись в обратном направлении . Вы создаете подпись и пытаетесь прикрепить ее к JWT Headers + Payload. Вместо этого вы хотите взять JWT Headers + Payload и подписать эти данные, а затем прикрепить подпись к JWT, чтобы создать Signed-JWT.
Код Psuedo, используя ваш исходный код:
body_b64 = base64url(JSON.stringify(header)) + "." + base64url(JSON.stringify(payload))
signature = sign(body_b64, name);
jwt = body_b64 + '.' + base64url(signature)
Примечание. Я не уверен, какой формат данных возвращает подпись signatureObject["0"].signature
. Возможно, вам придется преобразовать это перед преобразованием в base64.
[КОНЕЦ РЕДАКТИРОВАНИЯ]
Пример данных:
Заголовок JWT:
{
alg: RS256
kid: 0123456789abcdef62afcbbf01234567890abcdef
typ: JWT
}
Полезная нагрузка JWT:
{
"azp": "123456789012-gooddogsgotoheaven.apps.googleusercontent.com",
"aud": "123456789012-gooddogsgotoheaven.apps.googleusercontent.com",
"sub": "123456789012345678901",
"scope": "https://www.googleapis.com/auth/cloud-platform",
"exp": "1547806224",
"expires_in": "3596",
"email": "someone@example.com.com",
"email_verified": "true",
"access_type": "offline"
}
Алгоритм:
SHA256withRSA
Чтобы создать подписанный JWT (JWS):
Шаг 1:
Возьмите JWT Header и конвертируйте в Base-64. Давайте назовем это hdr_b64.
Шаг 2:
Возьмите полезную нагрузку JWT и конвертируйте в Base-64. Давайте назовем это payload_b64.
Шаг 3:
Объедините закодированный заголовок и полезную нагрузку с точкой .
между: hdr_b64
+ '.' + payload_b64`. Давайте назовем это body_b64.
Шаг 4:
Обычно JWS подписывается с SHA256 с помощью RSA, часто называемой «RS256» с использованием закрытого ключа:
signature = sign(body_b64, RS256, private_key)
Теперь конвертируйте подпись в Base-64. Позвольте назвать это signature_b64.
Для создания окончательного JWS:
jws = body_b64 + '.' + signature_b64.
Рекомендации:
Хотите использовать KMS для создания подписанных JWT? Я бы не рекомендовал это. Стоимость ключей доступа хранится в KMS. Подписанные JWT подписываются закрытым ключом и проверяются открытым ключом. Как вы собираетесь публиковать открытый ключ? Какой уровень производительности вам нужен для доступа к закрытым и открытым ключам (как часто вы будете подписывать и проверять)?
Когда вы создаете учетную запись службы в Google Cloud Platform, для вас создается пара ключей. Эта пара ключей имеет идентификатор с открытым ключом, доступным в Интернете, а закрытый ключ присутствует в файле учетных данных Json учетной записи службы. Я бы использовал служебную учетную запись для создания подписанных JWT вместо пары ключей в KMS.
Пример кода на Python для создания и подписи:
def create_signed_jwt(pkey, pkey_id, email, scope):
'''
Create a Signed JWT from a service account Json credentials file
This Signed JWT will later be exchanged for an Access Token
'''
import jwt
# Google Endpoint for creating OAuth 2.0 Access Tokens from Signed-JWT
auth_url = "https://www.googleapis.com/oauth2/v4/token"
issued = int(time.time())
expires = issued + expires_in # expires_in is in seconds
# Note: this token expires and cannot be refreshed. The token must be recreated
# JWT Headers
headers = {
"kid": pkey_id, # This is the service account private key ID
"alg": "RS256",
"typ": "JWT" # Google uses SHA256withRSA
}
# JWT Payload
payload = {
"iss": email, # Issuer claim
"sub": email, # Issuer claim
"aud": auth_url, # Audience claim
"iat": issued, # Issued At claim
"exp": expires, # Expire time
"scope": scope # Permissions
}
# Encode the headers and payload and sign creating a Signed JWT (JWS)
sig = jwt.encode(payload, pkey, algorithm="RS256", headers=headers)
return sig