获取 iOS 中包含的可信根证书的 PEM 文件(用于验证 gRPC)

Get a PEM file for a trusted root certificate included in iOS (for authenticating gRPC)

我有一个 iOS 应用程序,它使用 gRPC 与服务器通信。为了保护连接,服务器已颁发绑定到主机名的证书。我需要根据 iOS 设备上的根证书验证该证书。

gRPC 在 iOS 上提供的以下方法似乎可用于验证:

open class func setTLSPEMRootCerts(_ pemRootCert: String?, forHost host: String) throws

因此,要使用它,我需要提供要用于验证的根证书,以及服务器已针对其颁发证书的主机。主机部分很简单——它应该只是服务器颁发的证书绑定到的主机名。但是我坚持要获取根证书。

我找到了以下用于访问根证书的示例:

NSString *certsPath = [[NSBundle mainBundle] pathForResource:@"cacert_product" ofType:@"pem"];
NSError *error;
NSString *contentInUTF8 = [NSString stringWithContentsOfFile:certsPath
                                                    encoding:NSUTF8StringEncoding
                                                       error:&error];

在示例中,生成的 contentInUTF8 可以用作上述方法的证书参数。但是,示例中的资源名称 cacert_product 似乎是一个占位符;无论如何,我的设备上没有这样的资源,而且我不认为它会引用我想要使用的资源。

我想使用的证书是 iOS10 中包含的受信任根证书 this list 上的受信任根证书之一。不过我不知道如何访问它。

所以我的问题是:如何获取 iOS 设备上包含的受信任根证书之一的 PEM 文件?

我认为对您来说最简单的方法是向服务器证书颁发者询问 PEM 格式的根证书。他们通常有它。然后你就可以在 gRPC 中使用它了。

据我所知,无法在 iOS 中获取根证书列表。当您需要根据 iOS 根证书检查证书时,您可以使用策略(如 kSecPolicyAppleSSL)。但是你的情况是你没有在握手期间检查服务器证书的回调。

我将分两部分回答我自己的问题。

首先——正如 John Tracid 所指出的——无法像我最初想要的那样加载特定的根证书。看起来需要 PEM 文件的方法调用也不适合此用途。它应该只在像 John 建议的情况下使用,即当您想要添加您自己的证书时,您可以轻松访问它。

其次,为了让gRPC工作,我找到了这个方法和注释:

/**
 * Configures @c host with TLS/SSL Client Credentials and optionally trusted root Certificate
 * Authorities. If @c pemRootCerts is nil, the default CA Certificates bundled with gRPC will be
 * used.
 */
+ (BOOL)setTLSPEMRootCerts:(nullable NSString *)pemRootCerts
            withPrivateKey:(nullable NSString *)pemPrivateKey
             withCertChain:(nullable NSString *)pemCertChain
                   forHost:(nonnull NSString *)host
                     error:(NSError * _Nullable * _Nullable)errorPtr;

具体来说:If @c pemRootCerts is nil, the default CA Certificates bundled with gRPC will be used。 gRPC捆绑的证书列表不一定和iOS捆绑的一样,但看起来像pretty solid list,我想用的证书在两个里面。

所以为了让它工作,我只需要为 pem 通过 nil