tls 包
介绍
用于进行安全网络通信,提供启动 tls 服务器、连接 tls 服务器、发送数据、接收数据等功能。
使用本包需要外部依赖 OpenSSL 3
的 ssl
和 crypto
动态库文件,故使用前需安装相关工具:
- 对于
Linux
操作系统,可参考以下方式:- 如果系统的包管理工具支持安装
OpenSSL 3
开发工具包,可通过这个方式安装,并确保系统安装目录下含有libssl.so
、libssl.so.3
、libcrypto.so
和libcrypto.so.3
这些动态库文件,例如Ubuntu 22.04
系统上可使用sudo apt install libssl-dev
命令安装libssl-dev
工具包; - 如果无法通过上面的方式安装,可自行下载
OpenSSL 3.x.x
源码编译安装软件包,并确保安装目录下含有libssl.so
、libssl.so.3
、libcrypto.so
和libcrypto.so.3
这些动态库文件,然后可选择下面任意一种方式来保证系统链接器可以找到这些文件:- 在系统未安装 OpenSSL 的场景,安装时选择直接安装到系统路径下;
- 安装在自定义目录的场景,将这些文件所在目录设置到环境变量
LD_LIBRARY_PATH
以及LIBRARY_PATH
中。
- 如果系统的包管理工具支持安装
- 对于
Windows
操作系统,可按照以下步骤:- 自行下载
OpenSSL 3.x.x
源码编译安装 x64 架构软件包或者自行下载安装第三方预编译的供开发人员使用的OpenSSL 3.x.x
软件包; - 确保安装目录下含有
libssl.dll.a
(或libssl.lib
)、libssl-3-x64.dll
、libcrypto.dll.a
(或libcrypto.lib
)、libcrypto-3-x64.dll
这些库文件; - 将
libssl.dll.a
(或libssl.lib
)、libcrypto.dll.a
(或libcrypto.lib
) 所在的目录路径设置到环境变量LIBRARY_PATH
中,将libssl-3-x64.dll
、libcrypto-3-x64.dll
所在的目录路径设置到环境变量PATH
中。
- 自行下载
- 对于
macOS
操作系统,可参考以下方式:- 使用
brew install openssl@3
安装,并确保系统安装目录下含有libcrypto.dylib
和libcrypto.3.dylib
这两个动态库文件; - 如果无法通过上面的方式安装,可自行下载
OpenSSL 3.x.x
源码编译安装软件包,并确保安装目录下含有libcrypto.dylib
和libcrypto.3.dylib
这两个动态库文件,然后可选择下面任意一种方式来保证系统链接器可以找到这些文件:- 在系统未安装 OpenSSL 的场景,安装时选择直接安装到系统路径下;
- 安装在自定义目录的场景,将这些文件所在目录设置到环境变量
DYLD_LIBRARY_PATH
以及LIBRARY_PATH
中。
- 使用
如果未安装OpenSSL 3
软件包或者安装低版本的软件包,程序可能无法使用并抛出相关异常 TlsException: Can not load openssl library or function xxx.
。
主要接口
struct CipherSuite
public struct CipherSuite <: ToString & Equatable<CipherSuite>
结构体 CipherSuite
为 TLS 中的密码套件。
prop allSupported
public static prop allSupported: Array<CipherSuite>
功能:返回所有支持的密码套件。
返回值:存放密码套件的数组
func toString
public func toString(): String
功能:返回密码套件名称。
返回值:密码套件名称
operator func ==
public operator func ==(that: CipherSuite): Bool
功能:判断两个密码套件是否相等。
参数:
- that:被比较的密码套件对象
返回值:若相等,则返回 true
;反之,返回 false
operator func !=
public operator func !=(that: CipherSuite): Bool
功能:判断两个密码套件是否不等。
参数:
- that:被比较的密码套件对象
返回值:若不等,则返回 true
;反之,返回 false
class TlsSocket
public class TlsSocket <: StreamingSocket & ToString & Equatable<TlsSocket> & Hashable
TlsSocket 用于在客户端及服务端间创建加密传输通道。
func client
public static func client(
socket: StreamingSocket,
session!: ?TlsSession = None,
clientConfig!: TlsClientConfig = TlsClientConfig()
): TlsSocket
功能:根据传入的 StreamingSocket 实例创建指定地址的客户端 tls 套接字,该套接字可用于客户端 tls 握手及会话。
参数:
- socket:已连接到服务端的客户端 tcp 套接字
- session:TLS 会话 id,若存在可用的 TLS 会话, 则可通过该 id 恢复历史 TLS 会话,省去 TLS 建立连接时间,但使用该会话依然可能协商失败。默认为 None
- clientConfig:客户端配置,默认为 TlsClientConfig()
返回值:Tls 套接字
func server
public static func server(
socket: StreamingSocket,
sessionContext!: ?TlsSessionContext = None,
serverConfig!: TlsServerConfig
): TlsSocket
功能:根据传入的 StreamingSocket 实例创建指定地址的服务端 tls 套接字,该套接字可用于服务端 tls 握手及会话。
参数:
- socket:TCP 连接建立完成后接受到套接字
- sessionContext:TLS 会话 id, 若存在可用的 TLS 会话, 则可通过该 id 恢复历史 TLS 会话,省去 TLS 建立连接时间,但使用该会话依然可能协商失败。默认为 None
- serverConfig:服务端配置,默认为 TlsServerConfig()
返回值:Tls 套接字。
prop socket
public prop socket: StreamingSocket
功能:TlsSocket 创建所使用的 StreamingSocket。
异常:
- TlsException:本端配置为TLS的套接字已关闭时,抛出异常
prop readTimeout
public override mut prop readTimeout: ?Duration
功能:读写 TlsSocket 的读超时时间。
异常:
- SocketException:本端建连的底层TCP套接字关闭,抛出异常
- TlsException:本端配置为TLS的套接字已关闭时,抛出异常
- IllegalArgumentException:设定的读超时时间为负值时,抛出异常
prop writeTimeout
public override mut prop writeTimeout: ?Duration
功能:读写 TlsSocket 的写超时时间。
异常:
- SocketException:本端建连的底层TCP套接字关闭,抛出异常
- TlsException:本端配置为TLS的套接字已关闭时,抛出异常
- IllegalArgumentException:设定的写超时时间为负值时,抛出异常
prop localAddress
public override prop localAddress: SocketAddress
功能:读取 TlsSocket 的本地地址。
异常:
- SocketException:本端建连的底层TCP套接字关闭,抛出异常
- TlsException:本端配置为TLS的套接字已关闭时,抛出异常
prop remoteAddress
public override prop remoteAddress: SocketAddress
功能:读取 TlsSocket 的远端地址。
异常:
- SocketException:本端建连的底层TCP套接字关闭,抛出异常
- TlsException:本端配置为TLS的套接字已关闭时,抛出异常
prop alpnProtocolName
public prop alpnProtocolName: ?String
功能:读取协商到的应用层协议名称。
异常:
- TlsException:当套接字未完成TLS握手或本端TLS套接字已关闭时,抛出异常
- IllegalMemoryException:内存申请失败时,抛出异常
prop tlsVersion
public prop tlsVersion: TlsVersion
功能:读取协商到的 TLS 版本。
异常:
- TlsException:当套接字未完成TLS握手或本端TLS套接字已关闭时,抛出异常
prop session
public prop session: ?TlsSession
功能:读取 Tls 会话 id , 客户端会在握手成功后捕获当前会话的 id ,可使用该 id 重用该会话,省去 TLS 建立连接时间。连接建立未成功时,返回 None。
服务端不做捕获因此始终为 None。
异常:
- TlsException:当套接字未完成TLS握手,抛出异常
prop domain
public prop domain: ?String
功能:读取协商到的服务端主机名称。
- TlsException:当套接字未完成TLS握手或本端TLS套接字已关闭时,抛出异常
prop serverCertificate
public prop serverCertificate: Array<X509Certificate>
功能:服务器证书链由服务器提供或在服务器配置中预先配置。在服务端获取时为本端证书,在客户端获取时为对端证书。
这是可选的,因为服务器可能会跳过发送证书链。
这通常无效,但可以通过提供接受此类服务器的自定义 TLS 客户端配置来允许。
- TlsException:当套接字未完成TLS握手或本端TLS套接字已关闭时,抛出异常
prop clientCertificate
public prop clientCertificate: ?Array<X509Certificate>
功能:客户端提供的客户端证书。在客户端获取时为本端证书,在服务端获取时为对端证书。
异常:
- TlsException:当套接字未完成TLS握手或本端TLS套接字已关闭时,抛出异常
注意:当客户端会话恢复时,它可能会丢失。
prop peerCertificate
public prop peerCertificate: ?Array<X509Certificate>
功能:对端证书(如果对端提供)。
注意:在客户端获取时同 serverCertificate ,在服务端获取时同 clientCertificate。
异常:
- TlsException:当套接字未完成TLS握手或本端TLS套接字已关闭时,抛出异常
prop cipherSuite
public prop cipherSuite: CipherSuite
功能:握手后协商到的加密套。
密码套件包含加密算法、用于消息认证的散列函数、密钥交换算法。
异常:
- TlsException:当套接字未完成TLS握手或本端TLS套接字已关闭时,抛出异常
func handshake
public func handshake(timeout!: ?Duration = None): Unit
功能:TLS 握手。不支持重新协商握手,因此只能被调用一次。当调用对象可以为客户端或者服务端的 TlsSocket。
参数:
- timeout:握手超时时间,默认为 None
异常:
- SocketException:本端建连的底层 TCP 套接字关闭,抛出异常
- SocketTimeoutException: 底层 TCP 套接字连接超时时,抛出异常
- TlsException:当握手已经开始或者已经结束,抛出异常或当握手阶段出现系统错误时,抛出异常
- IllegalArgumentException: 设定的握手超时时间为负值时,抛出异常
func read
public override func read(buffer: Array<Byte>): Int64
功能:TlsSocket 读取数据。
参数:
- buffer:存储读取到的数据内容的容器
返回值:读取到的数据内容字节数
异常:
- SocketException:本端建连的底层TCP套接字关闭,抛出异常
- TlsException:当 buffer 为空,或者 TlsSocket 未连接,或读取数据出现系统错误等
func write
public func write(buffer: Array<Byte>): Unit
功能:TlsSocket 发送数据。
参数:
- buffer:存储将要发送的数据内容的容器
异常:
- SocketException:本端建连的底层TCP套接字关闭,抛出异常
- TlsException:当套接字已关闭,或者 TlsSocket 未连接,或写入数据出现系统错误等
func close
public func close(): Unit
功能:关闭套接字。
异常:
- SocketException:底层连接无法关闭时,抛出异常
func isClosed
public func isClosed(): Bool
功能:返回套接字是否关闭的状态。
返回值:连接断开返回 true;否则,返回 false
func toString
public func toString(): String
功能:套接字状态。
返回值:该 tls 连接字符串
operator func ==
public override operator func ==(other: TlsSocket)
功能:套接字间判等。
参数:
- other:对比的套接字
返回值:对比的套接字相同返回 true;否则,返回 false
operator func !=
public override operator func !=(other: TlsSocket)
功能:套接字间判不等。
参数:
- other:对比的套接字
返回值:对比的套接字不同返回 true;否则,返回 false
func hashCode
public override func hashCode(): Int64
功能:返回 tls 套接字对象的哈希值。
返回值:对 tls 套接字对象进行哈希计算后得到的结果
enum TlsVersion
public enum TlsVersion <: ToString {
| V1_2
| V1_3
| Unknown
}
TLS 协议版本
V1_2
V1_2
功能:表示 TLS 1.2。
V1_3
V1_3
功能:表示 V1_3。
Unknown
Unknown
功能:表示未知协议版本。
func toString
public override func toString(): String
功能:返回当前 TlsVersion
的字符串表示。
返回值:当前 TlsVersion
的字符串表示
enum CertificateVerifyMode
public enum CertificateVerifyMode {
| Default
| TrustAll
| CustomCA(Array<X509Certificate>)
}
证书认证模式,TCP 连接建立成功后,客户端和服务端可交换证书,Default 模式使用系统证书。 在开发测试阶段,可使用 TrustAll 模式,该模式表示本端不作对对端证书的校验。此模式本端信任任意建立连接对象,一般仅在开发测试阶段使用。 CustomCA 模式可使用用户配置的证书地址,适用于用户证书无法设置为系统证书的场景。
Default
Default
功能:表示默认验证模式:根据系统CA验证证书。
TrustAll
TrustAll
功能:表示信任所有证书。
CustomCA
CustomCA(Array<X509Certificate>)
功能:表示根据提供的CA列表进行验证。
enum TlsClientIdentificationMode
public enum TlsClientIdentificationMode {
| Disabled
| Optional
| Required
}
服务端对客户端证书的认证模式。
Disabled
Disabled
功能:表示服务端不校验客户端证书,客户端可以不发送证书和公钥,即单向认证。
Optional
Optional
功能:表示服务端校验客户端证书,但客户端可以不提供证书及公钥,不提供时则单向认证,提供时则为双向认证。
Required
Required
功能:表示服务端校验客户端证书,并且要求客户端必须提供证书和公钥,即双向认证。
enum HashType
public enum HashType <: ToString & Equatable<HashType> {
| SHA512
| SHA384
| SHA256
| SHA224
| SHA1
}
功能:在签名前使用的 Hash 算法类型,参见 RFC5246 7.4.1.4.1。
SHA512
SHA512
功能:创建一个 SHA512
类型的枚举实例,表示签名前使用的 Hash 算法类型为 SHA512。
SHA384
SHA384
功能:创建一个 SHA384
类型的枚举实例,表示签名前使用的 Hash 算法类型为 SHA384。
SHA256
SHA256
功能:创建一个 SHA256
类型的枚举实例,表示签名前使用的 Hash 算法类型为 SHA256。
SHA224
SHA224
功能:创建一个 SHA224
类型的枚举实例,表示签名前使用的 Hash 算法类型为 SHA224。
SHA1
SHA1
功能:创建一个 SHA1
类型的枚举实例,表示签名前使用的 Hash 算法类型为 SHA1。
func toString
public func toString(): String
功能:转换为字符串。
返回值:转换后的字符串
operator func ==
public operator func ==(other: HashType): Bool
功能:判等。
参数:
- other: 对比的签名前使用的 Hash 算法类型
返回值:相同返回 true;否则,返回 false
operator func !=
public operator func !=(other: HashType): Bool
功能:判不等。
参数:
- other: 对比的签名前使用的 Hash 算法类型
返回值:不相同返回 true;否则,返回 false
enum SignatureType
public enum SignatureType <: ToString & Equatable<SignatureType> {
| ECDSA
| DSA
| RSA
}
功能:签名算法类型,用于认证真实性。参见 RFC5246 7.4.1.4.1。
ECDSA
ECDSA
功能:创建一个 ECDSA
类型的枚举实例,表示采用椭圆曲线数字签名算法。
DSA
DSA
功能:创建一个 DSA
类型的枚举实例,表示采用数字签名算法。
RSA
RSA
功能:创建一个 RSA
类型的枚举实例,表示采用 RSA 加密算法。
func toString
public func toString(): String
功能:转换为字符串。
返回值:转换后的字符串
operator func ==
public operator func ==(other: SignatureType) : Bool
功能:判等。
参数:
- other: 对比的签名算法类型
返回值:相同返回 true;否则,返回 false
operator func !=
public operator func !=(other: SignatureType) : Bool
功能:判不等。
参数:
- other: 对比的签名算法类型
返回值:不相同返回 true;否则,返回 false
enum SignatureSchemeType
public enum SignatureSchemeType <: ToString & Equatable<SignatureSchemeType> {
| RSA_PKCS1_SHA256
| RSA_PKCS1_SHA384
| RSA_PKCS1_SHA512
| ECDSA_SECP256R1_SHA256
| ECDSA_SECP384R1_SHA384
| ECDSA_SECP521R1_SHA512
| RSA_PSS_RSAE_SHA256
| RSA_PSS_RSAE_SHA384
| RSA_PSS_RSAE_SHA512
| ED25519
| ED448
| RSA_PSS_PSS_SHA256
| RSA_PSS_PSS_SHA384
| RSA_PSS_PSS_SHA512
}
功能: 加密算法类型,用于保护网络通信的安全性和隐私性。
RSA_PKCS1_SHA256
RSA_PKCS1_SHA256
功能:创建一个 RSA_PKCS1_SHA256
类型的枚举实例,表示加密算法类型使用 RSA_PKCS1_SHA256。
RSA_PKCS1_SHA384
RSA_PKCS1_SHA384
功能:创建一个 RSA_PKCS1_SHA384
类型的枚举实例,表示加密算法类型使用 RSA_PKCS1_SHA384。
RSA_PKCS1_SHA512
RSA_PKCS1_SHA512
功能:创建一个 RSA_PKCS1_SHA512
类型的枚举实例,表示加密算法类型使用 RSA_PKCS1_SHA512。
ECDSA_SECP256R1_SHA256
ECDSA_SECP256R1_SHA256
功能:创建一个 ECDSA_SECP256R1_SHA256
类型的枚举实例,表示加密算法类型使用 ECDSA_SECP256R1_SHA256。
ECDSA_SECP384R1_SHA384
ECDSA_SECP384R1_SHA384
功能:创建一个 ECDSA_SECP384R1_SHA384
类型的枚举实例,表示加密算法类型使用 ECDSA_SECP384R1_SHA384。
ECDSA_SECP521R1_SHA512
ECDSA_SECP521R1_SHA512
功能:创建一个 ECDSA_SECP521R1_SHA512
类型的枚举实例,表示加密算法类型使用 ECDSA_SECP521R1_SHA512。
RSA_PSS_RSAE_SHA256
RSA_PSS_RSAE_SHA256
功能:创建一个 RSA_PSS_RSAE_SHA256
类型的枚举实例,表示加密算法类型使用 RSA_PSS_RSAE_SHA256。
RSA_PSS_RSAE_SHA384
RSA_PSS_RSAE_SHA384
功能:创建一个 RSA_PSS_RSAE_SHA384
类型的枚举实例,表示加密算法类型使用 RSA_PSS_RSAE_SHA384。
RSA_PSS_RSAE_SHA512
RSA_PSS_RSAE_SHA512
功能:创建一个 RSA_PSS_RSAE_SHA512
类型的枚举实例,表示加密算法类型使用 RSA_PSS_RSAE_SHA384。
ED25519
ED25519
功能:创建一个 ED25519
类型的枚举实例,表示加密算法类型使用 ED25519
ED448
ED448
功能:创建一个 ED448
类型的枚举实例,表示加密算法类型使用 ED448。
RSA_PSS_PSS_SHA256
RSA_PSS_PSS_SHA256
功能:创建一个 RSA_PSS_PSS_SHA256
类型的枚举实例,表示加密算法类型使用 RSA_PSS_PSS_SHA256。
RSA_PSS_PSS_SHA384
RSA_PSS_PSS_SHA384
功能:创建一个 RSA_PSS_PSS_SHA384
类型的枚举实例,表示加密算法类型使用 RSA_PSS_PSS_SHA384。
RSA_PSS_PSS_SHA512
RSA_PSS_PSS_SHA512
功能:创建一个 RSA_PSS_PSS_SHA512
类型的枚举实例,表示加密算法类型使用 RSA_PSS_PSS_SHA512。
func toString
public func toString(): String
功能:转换为字符串。
返回值:转换后的字符串
operator func ==
public operator func ==(other: SignatureSchemeType): Bool
功能:判等。
参数:
- other: 对比的加密算法类型
返回值:相同返回 true;否则,返回 false
operator func !=
public operator func !=(other: SignatureSchemeType): Bool
功能:判不等。
参数:
- other: 对比的加密算法类型
返回值:不相同返回 true;否则,返回 false
功能:哈希和签名算法列表。
enum SignatureAlgorithm
public enum SignatureAlgorithm <: ToString & Equatable<SignatureAlgorithm> {
| SignatureAndHashAlgorithm(SignatureType, HashType)
| SignatureScheme(SignatureSchemeType)
}
功能: 签名算法类型,签名算法用于确保传输数据的身份验证、完整性和真实性。
SignatureAndHashAlgorithm
SignatureAndHashAlgorithm(SignatureType, HashType)
功能:自 TLS 1.2 后出现,包含签名和哈希算法类型。
SignatureScheme
SignatureScheme(SignatureSchemeType)
功能:自 TLS 1.3 后出现,更为现代的指定签名算法的方式。
func toString
public func toString():String
功能:转换为字符串。
返回值:转换后的字符串
operator func ==
public operator func ==(other: SignatureAlgorithm) : Bool
功能:判等。
参数:
- other: 对比的签名算法类型
返回值:相同返回 true;否则,返回 false
operator func !=
public operator func !=(other: SignatureAlgorithm) : Bool
功能:判不等。
参数:
- other: 对比的签名算法类型
返回值:不相同返回 true;否则,返回 false
struct TlsClientConfig
public struct TlsClientConfig {
public init()
public var verifyMode: CertificateVerifyMode = CertificateVerifyMode.Default
}
客户端配置。
verifyMode
public var verifyMode: CertificateVerifyMode = CertificateVerifyMode.Default
功能:设置或获取证书认证模式,默认为 Default。
keylogCallback
public var keylogCallback: ?(TlsSocket, String) -> Unit = None
功能:握手过程的回调函数,提供 TLS 初始秘钥数据,用于调试和解密记录使用。
init
public init()
功能:构造 TlsClientConfig。
prop clientCertificate
public mut prop clientCertificate: ?(Array<X509Certificate>, PrivateKey)
功能:客户端证书和私钥。
prop domain
public mut prop domain: ?String
功能:读写要求的服务端主机地址 (SNI), None 表示不要求。
异常:
- IllegalArgumentException:参数有 '\0' 字符时,抛出异常
prop alpnProtocolsList
public mut prop alpnProtocolsList: Array<String>
功能:要求的应用层协议名称。若列表为空,则客户将不协商应用层协议。
异常:
- IllegalArgumentException:列表元素有 '\0' 字符时,抛出异常
prop cipherSuitesV1_2
public mut prop cipherSuitesV1_2: ?Array<String>
功能:基于 TLS 1.2 协议下的加密套。
异常:
- IllegalArgumentException:列表元素有 '\0' 字符时,抛出异常
prop cipherSuitesV1_3
public mut prop cipherSuitesV1_3: ?Array<String>
功能:基于 TLS 1.3 协议下的加密套。
异常:
- IllegalArgumentException:列表元素有 '\0' 字符时,抛出异常
prop minVersion
public mut prop minVersion: TlsVersion
功能:支持的 TLS 最小的版本。
注意:当仅设置 minVersion 而未设置 maxVersion ,或设置的 minVersion 高于 maxVersion ,将会在握手阶段抛出 TlsException。
prop maxVersion
public mut prop maxVersion: TlsVersion
功能:支持的 TLS 最大的版本。
注意:当仅设置 maxVersion 而未设置 minVersion ,或设置的 maxVersion 低于 minVersion ,将会在握手阶段抛出 TlsException。
prop signatureAlgorithms
public mut prop signatureAlgorithms: ?Array<SignatureAlgorithm>
功能:指定保序的签名和哈希算法。在值为 None 或者列表为空时,客户端会使用默认的列表。指定列表后,客户端可能不会发送不合适的签名算法。 参见 RFC5246 7.4.1.4.1.(TLS 1.2), RFC8446 4.2.3. (TLS 1.3)。
prop securityLevel
public mut prop securityLevel: Int32
功能:指定客户端的安全级别,默认值为2,可选参数值在 0-5 内,参数值含义参见 openssl-SSL_CTX_set_security_level 说明。
struct TlsServerConfig
public struct TlsServerConfig {
public var verifyMode: CertificateVerifyMode = CertificateVerifyMode.Default
public var clientIdentityRequired: TlsClientIdentificationMode = Disabled
public init(certChain: Array<X509Certificate>, certKey: PrivateKey)
}
服务端配置
verifyMode
public var verifyMode: CertificateVerifyMode = CertificateVerifyMode.Default
功能:设置或获取认证模式,默认认证系统证书。
clientIdentityRequired
public var clientIdentityRequired: TlsClientIdentificationMode = Disabled
功能:设置或获取服务端要求客户端的认证模式,默认不要求客户端认证服务端证书,也不要求客户端发送本端证书。
keylogCallback
public var keylogCallback: ?(TlsSocket, String) -> Unit = None
功能:握手过程的回调函数,提供 TLS 初始秘钥数据,用于调试和解密记录使用。
init
public init(certChain: Array<X509Certificate>, certKey: PrivateKey)
功能:构造 TlsServerConfig 对象。
参数:
- certChain:证书对象
- certKey:私钥对象
prop serverCertificate
public mut prop serverCertificate: (Array<X509Certificate>, PrivateKey)
功能:服务端证书和对应的私钥文件。
prop supportedAlpnProtocols
public mut prop supportedAlpnProtocols: Array<String>
功能:应用层协商协议,若客户端尝试协商该协议,服务端将与选取其中相交的协议名称。若客户端未尝试协商协议,则该配置将被忽略。
异常:
- IllegalArgumentException:列表元素有 '\0' 字符时,抛出异常
prop cipherSuitesV1_2
public mut prop cipherSuitesV1_2: Array<String>
功能:基于 TLS 1.2 协议下的加密套。
异常:
- IllegalArgumentException:列表元素有 '\0' 字符时,抛出异常
prop cipherSuitesV1_3
public mut prop cipherSuitesV1_3: Array<String>
功能:基于 TLS 1.3 协议下的加密套。
异常:
- IllegalArgumentException:列表元素有 '\0' 字符时,抛出异常
prop minVersion
public mut prop minVersion: TlsVersion
功能:支持的最小 TLS 版本。
注意:当仅设置 minVersion 而未设置 maxVersion ,或设置的 minVersion 高于 maxVersion ,将会在握手阶段抛出 TlsException。
prop maxVersion
public mut prop maxVersion: TlsVersion
功能:支持的最大 TLS 版本。
注意:当仅设置 maxVersion 而未设置 minVersion ,或设置的 maxVersion 低于 minVersion ,将会在握手阶段抛出 TlsException。
prop securityLevel
public mut prop securityLevel: Int32
功能:指定服务端的安全级别,默认值为2,可选参数值在 0-5 内,参数值含义参见 openssl-SSL_CTX_set_security_level 说明。
异常:
- IllegalArgumentException: 当配置值不在 0-5 范围内时,抛出异常
prop dhParameters
public mut prop dhParameters: ?DHParamters
功能:指定服务端的 DH 密钥参数,默认为 None, 默认情况下使用 openssl 自动生成的参数值。
struct TlsSession
public struct TlsSession <: Equatable<TlsSession> & ToString & Hashable
当客户端 TLS 握手成功后,将会生成一个会话,当连接因一些原因丢失后,客户端可以通过这个会话 id 复用此次会话,省略握手流程。
此结构体表示已建立的客户端会话。此结构体实例用户不可创建,其内部结构对用户不可见。
operator func ==
public override operator func ==(other: TlsSession)
功能:判等。
参数:
- other:被比较的会话对象
返回值:若会话对象相同,返回 true;否则,返回 false
operator func !=
public override operator func !=(other: TlsSession)
功能:判不等。
参数:
- other:被比较的会话对象
返回值:若会话对象不同,返回 true;否则,返回 false
func toString
public override func toString(): String
功能:生成会话 id 字符串。
返回值:TlsSession(会话 id 字符串)
func hashCode
public override func hashCode(): Int64
功能:生成会话 id 哈希值。
返回值:会话 id 哈希值
class TlsSessionContext
public class TlsSessionContext <: Equatable<TlsSessionContext> & ToString
当客户端尝试恢复会话时,双方都必须确保他们正在恢复与合法对端的会话。TlsSessionContext 会做以下两件事情: 1. 验证客户端。 2. 给客户端提供信息,确保客户端所连接的服务端仍为相同实例。
func fromName
public static func fromName(name: String): TlsSessionContext
功能:通过 TlsSessionContext 保存的名称获取 TlsSessionContext 对象该名称用于区分 TLS 服务器,因此客户端依赖此名称来避免意外尝试恢复与错误的服务器的连接这里不一定使用加密安全名称,因为底层实现可以完成这项工作从此函数返回的具有相同名称的两个会话上下文可能不相等,并且不保证可替换,尽管它们是从相同的名称创建的因此,服务器实例应该在整个生命周期内创建一个会话上下文,并且在每次 TlsSocket.server() 调用中使用它。
参数:
- name:会话上下文名称
返回值:会话上下文
operator func ==
public override operator func ==(other: TlsSessionContext)
功能:判等。
参数:
- other:被比较的会话上下文对象
返回值:若 TlsSessionContext 对象相同,返回 true;否则,返回 false
operator func !=
public override operator func !=(other: TlsSessionContext)
功能:判不等。
参数:
- other:被比较的会话上下文对象
返回值:若 TlsSessionContext 对象不同,返回 true;否则,返回 false
func toString
public override func toString(): String
功能:生成会话上下文名称字符串。
返回值:TlsSessionContext(会话上下文名称字符串)
class TlsException
public class TlsException <: Exception {
public init()
public init(message: String)
}
TLS 处理出现错误时抛出的异常
init
public init()
功能:构造异常。
init
public init(message: String)
功能:构造异常。
参数:
- message:异常信息
示例
客户端示例
from std import fs.*, socket.*
from net import tls.*
from crypto import x509.{X509Certificate,PrivateKey}
main() {
var config = TlsClientConfig()
config.verifyMode = TrustAll
config.alpnProtocolsList = ["h2"]
// 用于恢复会话
var lastSession: ?TlsSession = None
while (true) { // 重新连接环路
try (socket = TcpSocket("127.0.0.1", 8443)) {
socket.connect() // 首先进行 TCP 连接
try (tls = TlsSocket.client(socket, clientConfig: config, session: lastSession)) {
try {
tls.handshake() // then we are negotiating TLS
lastSession = tls.session // 如果成功协商下一次重新连接,将记住会话
} catch (e: Exception) {
lastSession = None // 如果协商失败,将删除会话
throw e
}
// tls实例已完成
tls.write("Hello, peer! Let's discuss our personal secrets.\n".toArray())
}
} catch (e: Exception) {
println("client connection failed ${e}, retrying...")
}
}
}
服务端示例
from std import fs.*, socket.*
from net import tls.*
from crypto import x509.{X509Certificate,PrivateKey}
let certificatePath = "./files/apiserver.crt"
let certificateKeyPath = "./files/apiserver.key"
main() {
// 对证书以及私钥进行解析
let pem = readTextFromFile(certificatePath)
let keyText = readTextFromFile(certificateKeyPath)
let certificate = X509Certificate.decodeFromPem(pem)
let privateKey = PrivateKey.decodeFromPem(keyText)
let config = TlsServerConfig(certificate, privateKey)
//可选:允许恢复TLS会话
let sessions= TlsSessionContext.fromName("my-server")
try (server = TcpServerSocket(bindAt:8443)) {
server.bind()
server.acceptLoop { clientSocket =>
try (tls = TlsSocket.server(clientSocket, serverConfig: config, sessionContext: sessions)) {
tls.handshake()
let buffer = Array<Byte>(100, item: 0)
tls.read(buffer)
println(buffer) // operate received data.
}
}
}
}
// 简化示例代码的辅助函数
extend TcpServerSocket {
func acceptLoop(handler: (TcpSocket) -> Unit) {
while (true) {
let client = accept()
spawn {
try {
handler(client)
} finally {
client.close()
}
}
}
}
}
func readTextFromFile(path: String): String {
var str = ""
try (file = File(path, OpenOption.Open(true, false))) {
str = String.fromUtf8(file.readToEnd())
}
str
}
证书热更新
from std import fs.*, socket.*
from net import tls.*
from crypto import x509.{X509Certificate,PrivateKey}
class MyServer {
private var currentConfig: TlsServerConfig
init(initialConfig: TlsServerConfig) { currentConfig = initialConfig }
/**
* 更改带有密钥的证书只会影响新的连接
*/
public mut prop certificate: (Array<X509Certificate>, PrivateKey) {
get() { currentConfig.serverCertificate }
set(newCertificate) { currentConfig.serverCertificate = newCertificate }
}
public func onAcceptedConnection(client: StreamingSocket) {
try (tls = TlsSocket.server(client, serverConfig: currentConfig)) {
tls.handshake()
}
}
}
服务端证书及公钥在一份文件中
from std import fs.*, socket.*, collection.*
from net import tls.*
from crypto import x509.{X509Certificate,PrivateKey, Pem, PemEntry,DerBlob}
let certificatePath = "/etc/myserver/cert-and-key.pem"
func parsePem(text: String): (Array<X509Certificate>, PrivateKey) {
let pem = Pem.decode(text)
let chain = pem |>
filter<PemEntry> { entry => entry.label == PemEntry.LABEL_CERTIFICATE } |>
map<PemEntry, X509Certificate> { entry => X509Certificate.decodeFromDer(entry.body ?? DerBlob()) } |>
collectArray
let key = (pem |>
filter<PemEntry> { entry => entry.label == PemEntry.LABEL_PRIVATE_KEY} |>
map<PemEntry, PrivateKey> { entry => PrivateKey.decodeDer(entry.body ?? DerBlob()) } |>
first) ?? throw Exception("No private key found in the PEM file")
if (chain.isEmpty()) {
throw Exception("No certificates found in the PEM file")
}
return (chain, key)
}
func readTextFromFile(path: String): String {
var fileString = ""
try (file = File(path, OpenOption.Open(true, false))) {
fileString = String.fromUtf8(file.readToEnd())
()
}
fileString
}
main() {
// 对证书及私钥进行解析
let pem = readTextFromFile(certificatePath)
let (certificate, privateKey) = parsePem(pem)
var _ = TlsServerConfig(certificate, privateKey)
// 进行https服务,请参阅其他服务器示例
}