Dart SecureSocket
最后修改于 2025 年 4 月 4 日
Dart 中的 SecureSocket
类使用 TLS/SSL 协议提供安全的网络通信。它对于加密的客户端-服务器应用程序至关重要。
SecureSocket 使用加密封装原始套接字,确保数据机密性和完整性。它是 Dart dart:io
库的一部分,用于 I/O 操作。
基本定义
SecureSocket
是一个基于流的加密通信通道。它实现了与普通套接字相同的接口,但增加了安全功能。
主要功能包括证书验证、协议协商和加密数据传输。它支持客户端和服务器端安全连接。
基本安全客户端连接
本示例展示了如何建立一个基本安全客户端连接。
main.dart
import 'dart:io'; Future<void> main() async { try { var socket = await SecureSocket.connect( 'example.com', 443, onBadCertificate: (cert) => true // For testing only ); print('Connected to ${socket.remoteAddress.address}'); socket.write('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n'); await socket.flush(); await socket.listen(print).asFuture(); await socket.close(); } catch (e) { print('Error: $e'); } }
我们连接到 example.com 的 443 端口(HTTPS)。`onBadCertificate` 回调允许测试自签名证书。我们发送一个 HTTP 请求并打印响应。
$ dart main.dart Connected to 93.184.216.34 HTTP/1.1 200 OK ...
带证书的安全服务器
本示例演示了创建一个简单的安全回显服务器。
main.dart
import 'dart:io'; Future<void> main() async { var context = SecurityContext() ..useCertificateChain('cert.pem') ..usePrivateKey('key.pem'); var server = await SecureServerSocket.bind( 'localhost', 4040, context, ); print('Secure server listening on ${server.port}'); await for (var socket in server) { socket.listen( (data) { print('Received: $data'); socket.add(data); }, onError: (e) => print('Error: $e'), onDone: () => print('Client disconnected'), ); } }
我们使用证书文件创建安全上下文,然后绑定一个安全服务器。服务器会回显所有收到的数据。实际使用中证书必须有效。
$ dart main.dart Secure server listening on 4040 Received: Hello
带证书验证的客户端
本示例展示了客户端中正确的证书验证。
main.dart
import 'dart:io'; Future<void> main() async { try { var socket = await SecureSocket.connect( 'example.com', 443, supportedProtocols: ['TLSv1.2', 'TLSv1.3'] ); print('Using protocol: ${socket.selectedProtocol}'); print('Peer certificate:'); print(socket.peerCertificate?.subject); var response = await socket .transform(utf8.decoder) .transform(LineSplitter()) .take(10) .toList(); print('Response headers:'); response.forEach(print); await socket.close(); } catch (e) { print('Connection failed: $e'); } }
我们使用协议限制进行连接,并检查服务器证书。响应以 UTF-8 文本形式读取,并进行适当的流转换。
$ dart main.dart Using protocol: TLSv1.3 Peer certificate: CN=example.com Response headers: HTTP/1.1 200 OK ...
双向 SSL 身份验证
本示例演示了双向 TLS 身份验证。
main.dart
import 'dart:io'; Future<void> main() async { var context = SecurityContext() ..useCertificateChain('client.pem') ..usePrivateKey('client_key.pem') ..setTrustedCertificates('ca.pem'); try { var socket = await SecureSocket.connect( 'secure.example.com', 9443, context: context, ); print('Mutual TLS established'); print('Peer cert: ${socket.peerCertificate?.subject}'); print('Our cert: ${socket.certificate?.subject}'); socket.write('PING'); var response = await socket.first; print('Response: ${String.fromCharCodes(response)}'); await socket.close(); } catch (e) { print('Mutual TLS failed: $e'); } }
客户端和服务器都使用证书进行身份验证。客户端出示其证书,并根据 CA 验证服务器证书。这提供了强大的双向身份验证。
$ dart main.dart Mutual TLS established Peer cert: CN=secure.example.com Our cert: CN=client.example.com Response: PONG
自定义安全上下文
本示例展示了如何创建具有特定设置的自定义安全上下文。
main.dart
import 'dart:io'; Future<void> main() async { var context = SecurityContext() ..setTrustedCertificates('custom_ca.pem') ..setAlpnProtocols(['h2', 'http/1.1'], false) ..setClientAuthorities('client_ca.pem'); var server = await SecureServerSocket.bind( 'localhost', 8443, context, requestClientCertificate: true, ); print('Custom secure server running'); await for (var socket in server) { print('ALPN: ${socket.selectedProtocol}'); print('Client cert: ${socket.peerCertificate?.subject}'); socket.transform(utf8.decoder).listen(print); socket.write('Welcome to secure server'); } }
我们使用特定的 CA、ALPN 协议和客户端证书要求配置自定义安全上下文。服务器会检查客户端证书并协商协议。
$ dart main.dart Custom secure server running ALPN: h2 Client cert: CN=testclient
最佳实践
- 验证证书:在生产环境中切勿跳过验证
- 使用强协议:优先使用 TLS 1.2 或更高版本
- 适当的错误处理:安全连接可能因多种原因失败
- 资源清理:完成后务必关闭套接字
- 证书管理:确保私钥安全
来源
本教程涵盖了 Dart 的 SecureSocket 类,并提供了实际示例,展示了客户端和服务器的使用、证书处理以及安全通信模式。
作者
列出 所有 Dart 教程。