Dart RawSecureSocket
最后修改于 2025 年 4 月 4 日
Dart 中的 `RawSecureSocket` 类使用 SSL/TLS 协议提供安全套接字通信。它对于客户端-服务器应用程序中的加密网络通信至关重要。
RawSecureSocket 扩展了 RawSocket,并增加了诸如加密、证书验证和安全握手等安全功能。它是 Dart `dart:io` 库的一部分,用于非 Web 应用程序。
基本定义
RawSecureSocket 是安全套接字通信的低级接口。它在提供原始字节访问的同时处理 SSL/TLS 加密。
主要功能包括安全连接建立、证书管理和加密数据传输。它可与客户端和服务器套接字配合使用。
基本安全客户端连接
此示例演示了如何建立基本安全客户端连接。
import 'dart:io';
Future<void> main() async {
try {
var socket = await RawSecureSocket.connect('example.com', 443);
print('Connected to ${socket.address.address}:${socket.port}');
socket.writeEventsEnabled = true;
socket.write(Uint8List.fromList('GET / HTTP/1.1\r\nHost: example.com\r\n\r\n'.codeUnits));
socket.listen((event) {
if (event == RawSocketEvent.read) {
print(String.fromCharCodes(socket.read()));
}
});
} catch (e) {
print('Connection failed: $e');
}
}
我们在端口 443(HTTPS)上连接到 example.com。连接后,我们发送一个 HTTP 请求并监听响应。套接字会自动处理所有加密。
$ dart main.dart Connected to 93.184.216.34:443 HTTP/1.1 200 OK ...
服务器证书验证
此示例演示了自定义证书验证。
import 'dart:io';
Future<void> main() async {
var context = SecurityContext.defaultContext;
context.setTrustedCertificates('path/to/cert.pem');
try {
var socket = await RawSecureSocket.connect(
'example.com',
443,
context: context,
onBadCertificate: (cert) {
print('Bad certificate: ${cert.subject}');
return false; // Reject invalid certificates
}
);
print('Connected with verified certificate');
socket.close();
} catch (e) {
print('Connection failed: $e');
}
}
我们创建一个带有自定义受信任证书的 SecurityContext。onBadCertificate 回调允许处理证书验证错误。这对于安全敏感的应用程序至关重要。
$ dart main.dart Connected with verified certificate
安全服务器实现
此示例演示了基本的安全服务器实现。
import 'dart:io';
Future<void> main() async {
var context = SecurityContext()
..useCertificateChain('server.crt')
..usePrivateKey('server.key');
var server = await SecureServerSocket.bind(
'localhost',
8443,
context,
backlog: 5
);
print('Secure server listening on ${server.address.address}:${server.port}');
server.listen((client) {
client.write('Hello secure client!\n');
client.close();
});
}
我们使用证书和私钥文件创建了一个安全服务器。服务器监听传入的连接并用一个简单消息进行响应。所有通信都会自动加密。
$ dart main.dart Secure server listening on 127.0.0.1:8443
客户端身份验证
此示例演示了双向 TLS 身份验证。
import 'dart:io';
Future<void> main() async {
var serverContext = SecurityContext()
..useCertificateChain('server.crt')
..usePrivateKey('server.key')
..setClientAuthorities('ca.crt')
..requestClientCertificate(true);
var server = await SecureServerSocket.bind(
'localhost',
8443,
serverContext
);
server.listen((client) {
var cert = client.peerCertificate;
if (cert != null) {
print('Client authenticated: ${cert.subject}');
}
client.close();
});
// Client with certificate
var clientContext = SecurityContext()
..useCertificateChain('client.crt')
..usePrivateKey('client.key')
..setTrustedCertificates('ca.crt');
var socket = await RawSecureSocket.connect(
'localhost',
8443,
context: clientContext
);
socket.close();
server.close();
}
服务器需要客户端证书进行身份验证。客户端在握手期间提供其证书。这实现了双向 TLS 身份验证。
$ dart main.dart Client authenticated: CN=client
处理安全套接字事件
此示例演示了全面的事件处理。
import 'dart:io';
Future<void> main() async {
var socket = await RawSecureSocket.connect('example.com', 443);
socket.listen((event) {
switch (event) {
case RawSocketEvent.read:
var data = socket.read();
print('Received: ${data?.length} bytes');
break;
case RawSocketEvent.write:
print('Ready to write');
break;
case RawSocketEvent.readClosed:
print('Read closed');
break;
case RawSocketEvent.closed:
print('Connection closed');
break;
}
}, onError: (e) {
print('Error: $e');
}, onDone: () {
print('Done');
});
socket.writeEventsEnabled = true;
socket.write(Uint8List.fromList('PING'.codeUnits));
await Future.delayed(Duration(seconds: 2));
socket.close();
}
我们处理各种套接字事件,包括数据接收、写入就绪和连接关闭。基于事件的 API 允许高效地处理异步套接字操作。
$ dart main.dart Ready to write Received: 142 bytes Connection closed Done
最佳实践
- 证书验证:始终验证服务器证书
- 上下文重用:为多个连接重用 SecurityContext
- 错误处理:处理所有套接字事件和错误
- 资源清理:完成后务必关闭套接字
- 协议选择:仔细配置支持的协议
来源
本教程涵盖了 Dart 的 RawSecureSocket 类,并通过实际示例展示了安全通信、证书处理和事件管理。
作者
列出 所有 Dart 教程。