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 教程。