如何将OpenSSL集成到Swift Pod框架中?
在Swift 3 Pod中集成OpenSSL以提取SSL证书组织信息
刚好之前帮朋友处理过类似的Swift 3 Pod集成OpenSSL的需求,给你整理了一套完整的流程,从集成到提取证书组织名称的代码都有,亲测能用:
1. 准备OpenSSL的iOS适配资源
首先你需要拿到适配iOS平台的OpenSSL静态库和头文件:
- 可以自己用脚本编译iOS版本的OpenSSL,或者找现成的编译好的包
- 把编译好的
libcrypto.a、libssl.a放到Pod项目的Vendor/OpenSSL/lib目录下 - 把OpenSSL的头文件目录
include/openssl放到Vendor/OpenSSL/include目录下
2. 配置Podspec文件
在你的Pod的.podspec里添加以下配置,确保OpenSSL的资源被正确引入到Pod模块中:
# 保留OpenSSL的文件结构 s.preserve_paths = 'Vendor/OpenSSL/**/*' # 设置头文件目录别名,方便Swift调用 s.header_dir = 'openssl' # 公开OpenSSL的头文件 s.public_header_files = 'Vendor/OpenSSL/include/openssl/*.h' # 指定引入的静态库 s.vendored_libraries = 'Vendor/OpenSSL/lib/libcrypto.a', 'Vendor/OpenSSL/lib/libssl.a' # 链接必要的库 s.libraries = 'crypto', 'ssl' # 配置编译参数 s.xcconfig = { 'HEADER_SEARCH_PATHS' => '$(PODS_TARGET_SRCROOT)/Vendor/OpenSSL/include', 'OTHER_LDFLAGS' => '-ObjC' }
3. 配置Swift与OpenSSL的桥接文件
因为OpenSSL是C语言库,Swift 3需要通过桥接文件来调用:
- 在Pod项目里创建
[你的Pod名称]-Bridging-Header.h文件,添加需要的OpenSSL头文件:
#include <openssl/x509.h> #include <openssl/pem.h> #include <openssl/bio.h>
- 回到Podspec,添加桥接文件的配置:
s.pod_target_xcconfig = { 'SWIFT_OBJC_BRIDGING_HEADER' => '$(PODS_TARGET_SRCROOT)/[你的Pod目录]/[你的Pod名称]-Bridging-Header.h' }
记得把[你的Pod名称]和[你的Pod目录]替换成实际的名称和路径。
4. 编写Swift代码提取证书组织名称
现在可以写Swift代码来解析SSL证书,提取组织名称(也就是X509证书里的O字段),给你一个封装好的函数:
import Foundation public func extractOrganizationName(fromCertificateData certData: Data) -> String? { // 初始化BIO对象读取证书数据 guard let bio = BIO_new(BIO_s_mem()) else { print("Failed to create BIO object") return nil } defer { BIO_free(bio) } // 将证书Data写入BIO let bytes = (certData as NSData).bytes BIO_write(bio, bytes, Int32(certData.count)) // 读取PEM格式的证书(如果是DER格式,替换成d2i_X509_bio) guard let x509Cert = PEM_read_bio_X509(bio, nil, nil, nil) else { print("Failed to parse PEM certificate") return nil } defer { X509_free(x509Cert) } // 获取证书的主体信息 guard let subjectName = X509_get_subject_name(x509Cert) else { print("Failed to get certificate subject") return nil } // 指定要提取的字段:组织名称(O) let organizationNID = OBJ_txt2nid("O") var resultBuffer: UnsafeMutablePointer<UInt8>? let bufferLength = X509_NAME_get_text_by_NID(subjectName, organizationNID, &resultBuffer, 0) guard bufferLength > 0, let buffer = resultBuffer else { print("Failed to extract organization name") return nil } // 转成Swift字符串并释放内存 let orgName = String(cString: buffer) OPENSSL_free(buffer) return orgName }
如果你的证书是DER格式,只需要把PEM_read_bio_X509换成d2i_X509_bio即可。
5. 测试功能
在Pod的测试代码里,用一个测试证书验证功能:
// 假设测试证书放在Pod的测试资源里 if let certPath = Bundle(for: YourTestClass.self).path(forResource: "test-cert", ofType: "pem"), let certData = try? Data(contentsOf: URL(fileURLWithPath: certPath)), let orgName = extractOrganizationName(fromCertificateData: certData) { print("证书组织名称:\(orgName)") } else { print("证书解析失败") }
一些注意事项
- 确保OpenSSL的静态库支持你需要的iOS架构(比如arm64、x86_64),不然会出现编译或运行时错误
- Swift 3里
Data转C指针的方式是(data as NSData).bytes,后续Swift版本有变化,但这里符合Swift 3的语法 - 一定要记得调用OpenSSL的内存释放函数(比如
BIO_free、X509_free),避免内存泄漏 - 如果你的Pod需要支持macOS等其他平台,需要对应调整OpenSSL的编译版本和Podspec配置
内容的提问来源于stack exchange,提问作者Shamil
相关产品推荐
相关产品推荐

