APIDoc Build Status - Master macOS iOS Linux Apache 2 Slack Status

BlueSSLService

用于 Swift 中 BlueSocket 的 SSL/TLS 插件框架,使用 Swift Package Manager。可在受支持的 Apple 平台(使用 Secure Transport)和 Linux(使用 OpenSSL)上运行。

先决条件

Swift

BlueSSLService 2.0 及更高版本支持 Swift 5.2+。对于旧版本的 Swift,请参阅旧版本的 BlueSSLService。

macOS

iOS

Linux

其他平台

注意:有关详细信息,请参见 Package.swift

构建

要从命令行构建 SSLService

% cd <path-to-clone>
% swift build

测试

要从命令行运行提供的 SSLService 单元测试

% cd <path-to-clone>
% swift build
% swift test

使用 BlueSSLService

开始之前

首先需要导入 SocketSSLService 框架。这可以通过以下方式完成

import Socket
import SSLService

创建配置

客户端和服务器至少需要以下配置项

或者

或者,如果使用 self-signed 证书

或者,如果在 Linux 上运行(目前),

或者,如果在 macOS 上运行

或者,

BlueSSLService 提供了五种创建 Configuration 的方法,支持上述场景。 只有最后一个版本在 Apple 平台上受支持。 在 Linux 上,所有版本都受支持。 这是由于当前 Apple Secure Transport 实现的限制。

注意 1:所有 证书私钥 文件必须是 PEM 格式。 如果通过 String 提供证书,则它必须是 PEM 格式。

注意 2:如果使用证书链文件,则证书必须是 PEM 格式,并且必须进行排序,从主题的证书(实际的客户端或服务器证书)开始,后跟中间 CA 证书(如果适用),并以最高级别(根)CA 结束。

注意 3:对于 API 的前两个版本,如果您的 私钥 包含在您的证书文件中,您可以省略此参数,并且 API 将使用为证书文件指定的相同文件名。

注意 4:如果您希望自定义使用的密码套件,可以通过在使用上述初始化程序之一时指定 cipherSuite 参数来实现。 如果未指定,则默认值在 Linux 上设置为 DEFAULT。 在 macOS 上,目前不支持设置此参数,尝试设置它将导致不可预测的结果。 请参阅下面的示例。

注意 5:如果您在 macOS 上运行,则必须使用 Configuration 的最后一种 init 形式,并提供 PKCS12 格式的证书链文件,并在需要时提供 password

示例

以下说明了如何使用上述 API 的第二种形式(在 Linux 上)创建配置,使用自签名证书文件作为密钥文件,而不提供证书链文件。 它还说明了如何将密码套件从默认值设置为 ALL

import SSLService

...

let myCertPath = "/opt/myApp/config/myCertificate.pem"
let myKeyPath = "/opt/myApp/config/myKeyFile.pem"

let myConfig = SSLService.Configuration(withCACertificateDirectory: nil, usingCertificateFile: myCertPath, withKeyFile: myKeyFile)

myConfig.cipherSuite = "ALL"

...

注意:此示例利用了 SSLService.Configuration.init 函数上可用的 default 参数。 此外,目前不支持在 macOS 上更改 cipher suite

创建和使用 SSLService

以下 API 用于创建 SSLService

创建 SSLService 后,可以将其应用于先前创建的刚创建的 Socket 实例。 这需要在使用 Socket 之前完成。 以下代码片段说明了如何执行此操作(再次使用 Linux)。 注意:为简洁起见,省略了异常处理。

import Socket
import SSLService

...

// Create the configuration...
let myCertPath = "/opt/myApp/config/myCertificate.pem"
let myKeyPath = "/opt/myApp/config/myKeyFile.pem"

let myConfig = SSLService.Configuration(withCACertificateDirectory: nil, usingCertificateFile: myCertPath, withKeyFile: myKeyFile)

// Create the socket...
var socket = try Socket.create()
guard let socket = socket else {
  fatalError("Could not create socket.")
}

// Create and attach the SSLService to the socket...
//  - Note: if you're going to be using the same 
//          configuration over and over, it'd be 
//          better to create it in the beginning 
//          as `let` constant.
socket.delegate = try SSLService(usingConfiguration: myConfig)

// Start listening...
try socket.listen(on: 1337)

上面的示例创建了一个 SSL server 套接字。 将 socket.listen 函数替换为 socket.connect 将导致创建一个 SSL client,如下所示

// Connect to the server...
try socket.connect(to: "someplace.org", port: 1337)

SSLService 处理安全数据传输的所有协商和设置。 用于启动连接的 API 是确定 Socket 设置为服务器还是客户端 Socket 的决定性因素。 listen() 将导致 Socket 设置为服务器套接字。 调用 connect() 会导致客户端设置。

扩展连接验证

如果您需要指定额外的验证逻辑,SSLService 提供了一种回调机制。 创建 SSLService 的实例后,您可以设置实例变量 verifyCallback。 此实例变量具有以下签名

public var verifyCallback: ((_ service: SSLService) -> (Bool, String?))? = nil

不需要设置此回调。 除非设置,否则默认为 nil。 传递给您的回调的第一个参数是具有此回调的 SSLService 的实例。 这将允许您访问 SSLService 实例的公共成员,以便进行额外的验证。 完成后,您的回调应返回一个元组。 第一个值是一个 Bool,指示例程的成功或失败。 第二个值是一个 optional String 值,用于在验证失败的情况下提供描述。 如果回调失败,内部验证函数将引发 exception重要提示:要有效使用此回调,需要了解平台的基础安全传输服务,supported Apple platforms 上的 Apple Secure TransportLinux 上的 OpenSSL

跳过连接验证

如果需要,SSLService 可以跳过连接验证。 为此,请在创建 SSLService 实例后将属性 skipVerification 设置为 true。 但是,如果设置了 verifyCallback 属性(如上所述),则无论此设置如何,都将调用该回调。 该属性的默认值为 false。 建议您在 production 环境中跳过连接验证,除非您通过 verificationCallback 提供验证。

社区

我们喜欢讨论服务器端 Swift 和 Kitura。 加入我们的 Slack 来认识团队!

许可证

此库已获得 Apache 2.0 许可。 完整的许可证文本可在 LICENSE 中找到。