ZetCode

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

最佳实践

来源

Dart SecureSocket 文档

本教程涵盖了 Dart 的 SecureSocket 类,并提供了实际示例,展示了客户端和服务器的使用、证书处理以及安全通信模式。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。自 2007 年以来,我一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在教授编程方面有十多年的经验。

列出 所有 Dart 教程