Подтвердите токен JWT с помощью RS256 или RS512 с помощью Swift iOS

Я создаю приложение iOS на Swift, которое должно иметь возможность проверять подпись токена JWT с помощью сертификата открытого ключа с использованием RS256 или RS512.

Я пытался найти библиотеки, поддерживающие такие функции, но у меня были проблемы с реализацией найденных мною.

Поэтому у меня вопрос, каков рекомендуемый способ реализации такой функциональности для приложения Swift iOS?

Идеальный сценарий - иметь возможность использовать один из признанных фреймворков на JWT.io. Единственная библиотека Swift на JWT.io, которая поддерживает RS256 или RS512, - это следующая библиотека: https://github.com/vapor/jwt

Функциональные возможности, которые поддерживает эта библиотека, идеальны, но они, однако, требуют реализации через Swift Package Manager и построены с использованием Vapor. Диспетчер пакетов Swift в настоящее время не поддерживается для iOS, но я читал, что существуют обходные пути, позволяющие заставить диспетчер пакетов Swift работать с приложениями iOS. Это обходные пути, которые можно использовать, если библиотека может работать в приложении iOS. Однако, поскольку библиотека создана для Vapor, мой вопрос в том, можно ли вообще заставить библиотеку работать в приложении iOS, которое я создаю?

Если невозможно использовать эту библиотеку, рекомендуются ли другие библиотеки? Если нет, то каков рекомендуемый способ реализации этой запрошенной функции? Существуют ли рекомендуемые библиотеки Objective-C, которые могут работать в приложении?

Заранее спасибо!

Изменить: Под проверкой я имею в виду, что я хотел бы убедиться, что подпись в токене верна, что означает, что токен JWT был подписан закрытым ключом на сервере, которому соответствует сертификат открытого ключа в приложении. Не просто декодировать полезную нагрузку Base64Check.

Изменить 2: я пытаюсь достичь функциональности, которая поддерживает асимметричные ключи, что означает, что секрет не должен храниться как на сервере, так и в клиентском приложении. Я пытаюсь добиться того, чтобы приложение содержало только несекретную информацию, следовательно, сертификат открытого ключа.


person smart_card_fan    schedule 26.04.2017    source источник
comment
Что вы имеете в виду под проверкой токена JWT? Просто прочтите этот жетон?   -  person Oleg Gordiichuk    schedule 26.04.2017
comment
Вы читали об этой библиотеке github.com/kylef/JSONWebToken.swift?   -  person Oleg Gordiichuk    schedule 26.04.2017
comment
Вот еще одна библиотека для этой проблемы: github.com/auth0/JWTDecode.swift   -  person Efren    schedule 15.03.2018
comment
@Efren эта библиотека только декодирует JWT, не проверяя их должным образом.   -  person dj-neza    schedule 15.03.2018


Ответы (1)


Не уверен, что вы все еще застряли на этом, но я был в той же ситуации, и мне потребовалось время, чтобы понять. В итоге я использовал модуль JWT, и эта статья. Обобщу свои выводы.

Из-за того, что Apple отказалась от OpenSSL в пользу своих собственных библиотек безопасности, на входе должен быть самоподписанный сертификат, содержащий открытый ключ. С OpenSSL сделайте что-то вроде этого, используя свой закрытый ключ в качестве ввода:

openssl req -key private_key.pem -new -x509 -days 3650 -out selfsigned_cert.pem

Затем преобразуйте формат PEM в DER, что в основном удаляет броню b64:

openssl x509 -outform der -in selfsigned_cert.pem -out selfsigned_cert.der

Добавьте файл .der в Supporting Files в вашем проекте Xcode, а затем прочтите данные сертификата с диска и base64 закодируйте их:

NSURL *fileURL = [NSURL fileURLWithPath:[bundle pathForResource: @"selfsigned_cert" ofType:@"der"]];
NSData *certificateData = [NSData dataWithContentsOfURL:fileURL];
// Probably want to do a nil-check on certificateData here
NSString *certificateStr = [JWTBase64Coder base64UrlEncodedStringWithData:certificateData];

А затем подключите его к декодеру JWT:

JWTBuilder *decodeBuilder = [JWTBuilder decodeMessage:token] // your JWT
  .secret(certificateStr)
  .algorithmName(algorithmName); // From your token or a predefined string
NSDictionary *payload = decodeBuilder.decode;

Вы можете проверить успешность декодирования / верификации, проверив наличие ошибки в построителе:

if(decodeBuilder.jwtError != nil) { /* do stuff */ }

Изменить: в качестве примечания. Преобразование в DER, а затем в кодирование b64 может показаться излишним, в основном это просто удаляет линии привязки из формата PEM. Причина, по которой у меня есть файл .der на диске, заключается в том, что мы можем использовать его напрямую с библиотеками безопасности, если нам нужно.

person Andreas Aronsson    schedule 02.05.2017
comment
Этот ответ очень полезен, и его следует принять. - person whitney13625; 23.06.2017
comment
Это сделало med намного ближе к архивированию моей цели, которая заключается в проверке JWT на iOS (swift), который был подписан с частным RS256. Но ответ кажется устаревшим, и модуль JWT обновлялся несколько раз. может ли кто-нибудь привести быстрый пример того, как это сделать? Нам все еще нужен самоподписанный сертификат или достаточно открытого ключа? - person iCediCe; 30.10.2017
comment
@iCediCe в этом ответе есть разговоры по одной из проблем в связанной библиотеке, но, насколько мне известно, пока никто этого не сделал. Сам ищу решение Swift .. - person dj-neza; 15.03.2018
comment
спасибо за это, но в моем случае он вылетает, когда SecCertificateCreateWithData (certificateData) становится равным нулю - person Siu Chung Chan; 21.04.2020