使用Swift iOS验证JWT令牌的RS256或RS512

4
我正在使用Swift构建一个iOS应用程序,需要能够使用公钥证书验证JWT令牌签名,使用RS256或RS512。我一直在寻找支持这些功能的库,但实现时遇到了问题。
我的问题是:在Swift iOS应用程序中实现此功能的推荐方式是什么?
理想情况下,应该能够使用JWT.io上的任何一个认可的框架。JWT.io上唯一支持RS256或RS512的Swift库是以下库: https://github.com/vapor/jwt
这个库支持的功能非常理想,但是它需要通过Swift Package Manager实现,并且使用Vapor构建。目前尚不支持将Swift Package Manager用于iOS,但我已经阅读到有解决方法可以让Swift Package Manager与iOS应用程序一起使用。如果该库可以在我正在构建的iOS应用程序中运行,则愿意采取这些解决方法。但是由于该库是为Vapor构建的,所以我的问题是是否可能使该库在我正在构建的iOS应用程序中运行?
如果不能使用此库,则推荐使用其他库吗?如果没有,那么实现此请求功能的推荐方式是什么?是否有推荐的Objective-C库可以在应用程序上运行?
谢谢! 注:通过验证,我指的是要验证令牌中的签名是否正确,也就是JWT令牌是否使用服务器上的私钥进行了签名,并且公钥证书与应用程序上的公钥证书相对应。不仅仅是解码Base64Check有效负载。
编辑2: 我想要实现的功能支持非对称密钥,这意味着密钥不能在服务器和客户端应用程序上都存储。我正在尝试实现应用程序仅包含非机密信息,因此需要一个公钥证书。

令牌验证是什么意思?只需读取此令牌吗? - Oleg Gordiichuk
你有没有看过这个库 https://github.com/kylef/JSONWebToken.swift ? - Oleg Gordiichuk
这是另一个针对该问题的库:https://github.com/auth0/JWTDecode.swift - Efren
@Efren 这个库只能解码 JWT,而不能像所需的那样验证它们。 - dj-neza
1个回答

5
我不确定你是否还卡在这个问题上,但我曾经处于完全相同的境地,花了一段时间才弄清楚。最终,我使用了JWT pod,并通过这篇文章得到了正确的指引。以下是我的总结。
由于苹果公司放弃了 OpenSSL 并采用了自己的 Security libs,所以输入必须是包含公钥的自签名证书。使用 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 文件添加到 Xcode 项目中的 Supporting Files 文件夹,然后从磁盘读取证书数据并进行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 */ }

编辑:顺带一提,将PEM格式转换为DER格式,然后再进行b64编码可能看起来有些多余,实际上只是移除了锚定行。我之所以在磁盘上有一个 .der 文件,是因为如果需要,我们可以直接使用安全库。


1
这个答案非常有帮助,应该被接受。 - whitney13625
1
这让我离实现我的目标更近了一步,即在iOS(Swift)上验证使用私有RS256签名的JWT。但是答案似乎已经过时了,而JWT pod已经更新了几次。是否有人可以提供一个Swift示例来说明如何做到这一点?我们是否仍然需要自签名证书,还是公钥就足够了? - iCediCe
@iCediCe,这个答案中链接的库的一个问题中有一些讨论,但据我所知,到目前为止还没有人做过。我自己也在寻找一个Swift解决方案。 - dj-neza
谢谢你的回复,但在我的情况下,当SecCertificateCreateWithData(certificateData)变为nil时,它会崩溃。 - Siu Chung Chan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接