007-网络安全协议

007-网络安全协议

难度:🔴 | 预计时间:120分钟 | 前置:006-数字证书与PKI体系

学习目标

  • 理解网络安全协议的设计原理和安全目标
  • 掌握SSL/TLS协议的握手过程和安全机制
  • 了解IPSec、SSH、HTTPS等重要安全协议
  • 熟悉无线网络安全协议(WPA/WPA2/WPA3)
  • 能够分析和配置各种网络安全协议

内容正文

网络安全协议概述

网络安全协议是在网络通信中提供安全服务的协议,通过密码学技术实现机密性、完整性、认证和不可否认性。

网络安全协议分层
应用层安全协议
HTTPS
S/MIME
PGP
SSH
传输层安全协议
SSL/TLS
DTLS
网络层安全协议
IPSec
IKE
数据链路层安全协议
WPA/WPA2/WPA3
802.1X
物理层安全
光纤加密
无线加密
安全协议设计原则
原则描述实现方式
最小权限只授予必要的访问权限细粒度访问控制
深度防御多层安全保护协议栈各层都有安全措施
故障安全系统故障时保持安全默认拒绝策略
开放设计安全不依赖于保密公开协议规范
完全中介所有访问都经过安全检查强制访问控制

SSL/TLS协议

SSL/TLS(Secure Sockets Layer/Transport Layer Security)是最重要的传输层安全协议。

TLS协议架构
TLS协议栈
TLS握手协议
TLS记录协议
TLS警报协议
TLS变更密码规范协议
ClientHello
ServerHello
证书交换
密钥交换
握手完成
数据分片
压缩
MAC计算
加密
传输
应用数据
TCP
TLS协议类设计
TLSConnection
-version: String
-cipher_suite: CipherSuite
-session_id: String
-state: ConnectionState
+handshake()
+send_data(data: bytes)
+receive_data()
+close_connection()
TLSHandshake
-client_random: bytes
-server_random: bytes
-premaster_secret: bytes
-master_secret: bytes
-session_keys: SessionKeys
+client_hello()
+server_hello()
+certificate_exchange()
+key_exchange()
+finished()
CipherSuite
-key_exchange: String
-authentication: String
-encryption: String
-mac: String
+encrypt(data: bytes)
+decrypt(data: bytes)
+sign(data: bytes)
+verify(signature: bytes)
Certificate
-subject: String
-issuer: String
-public_key: PublicKey
-validity_period: DateRange
-extensions: List<Extension>
+verify_signature()
+check_validity()
+get_public_key()
SessionKeys
-client_write_key: bytes
-server_write_key: bytes
-client_write_iv: bytes
-server_write_iv: bytes
-client_mac_key: bytes
-server_mac_key: bytes
+derive_keys(master_secret: bytes)
TLS握手过程详解
# 文件路径: crypto/tls_handshake.py
import ssl
import socket
import struct
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import os

class TLSHandshakeAnalyzer:
    """TLS握手分析器"""
    
    def __init__(self):
        self.client_random = None
        self.server_random = None
        self.premaster_secret = None
        self.master_secret = None
        self.session_keys = None
    
    def analyze_client_hello(self, client_hello_data):
        """分析ClientHello消息"""
        # 解析TLS版本
        tls_version = struct.unpack('>H', client_hello_data[0:2])[0]
        
        # 解析客户端随机数
        self.client_random = client_hello_data[2:34]
        
        # 解析会话ID长度
        session_id_length = client_hello_data[34]
        session_id = client_hello_data[35:35+session_id_length]
        
        # 解析密码套件
        offset = 35 + session_id_length
        cipher_suites_length = struct.unpack('>H', client_hello_data[offset:offset+2])[0]
        cipher_suites_data = client_hello_data[offset+2:offset+2+cipher_suites_length]
        
        cipher_suites = []
        for i in range(0, cipher_suites_length, 2):
            suite = struct.unpack('>H', cipher_suites_data[i:i+2])[0]
            cipher_suites.append(suite)
        
        return {
            'tls_version': f"0x{tls_version:04x}",
            'client_random': self.client_random.hex(),
            'session_id': session_id.hex() if session_id else None,
            'cipher_suites': [f"0x{suite:04x}" for suite in cipher_suites]
        }
    
    def generate_master_secret(self, premaster_secret, client_random, server_random):
        """生成主密钥"""
        # TLS 1.2 PRF函数实现
        def prf(secret, label, seed, length):
            """伪随机函数"""
            import hmac
            
            def p_hash(secret, seed, length):
                """P_hash函数"""
                result = b''
                a = seed
                
                while len(result) < length:
                    a = hmac.new(secret, a, hashes.SHA256()).digest()
                    result += hmac.new(secret, a + seed, hashes.SHA256()).digest()
                
                return result[:length]
            
            return p_hash(secret, label + seed, length)
        
        # 计算主密钥
        label = b"master secret"
        seed = client_random + server_random
        master_secret = prf(premaster_secret, label, seed, 48)
        
        self.master_secret = master_secret
        return master_secret
    
    def generate_session_keys(self, master_secret, client_random, server_random):
        """生成会话密钥"""
        def prf(secret, label, seed, length):
            import hmac
            
            def p_hash(secret, seed, length):
                result = b''
                a = seed
                
                while len(result) < length:
                    a = hmac.new(secret, a, hashes.SHA256()).digest()
                    result += hmac.new(secret, a + seed, hashes.SHA256()).digest()
                
                return result[:length]
            
            return p_hash(secret, label + seed, length)
        
        # 生成密钥材料
        label = b"key expansion"
        seed = server_random + client_random
        key_material = prf(master_secret, label, seed, 104)  # 假设AES-128-CBC-SHA
        
        # 分割密钥材料
        client_mac_key = key_material[0:20]      # SHA-1 MAC密钥
        server_mac_key = key_material[20:40]
        client_enc_key = key_material[40:56]     # AES-128加密密钥
        server_enc_key = key_material[56:72]
        client_iv = key_material[72:88]          # AES-128 IV
        server_iv = key_material[88:104]
        
        self.session_keys = {
            'client_mac_key': client_mac_key,
            'server_mac_key': server_mac_key,
            'client_enc_key': client_enc_key,
            'server_enc_key': server_enc_key,
            'client_iv': client_iv,
            'server_iv': server_iv
        }
        
        return self.session_keys

def demonstrate_tls_handshake():
    """演示TLS握手过程"""
    print("=== TLS握手过程演示 ===\n")
    
    # 1. ClientHello
    print("1. ClientHello")
    print("   - TLS版本: 1.2")
    print("   - 客户端随机数: 32字节")
    print("   - 支持的密码套件:")
    print("     * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
    print("     * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384")
    print("     * TLS_RSA_WITH_AES_128_CBC_SHA")
    
    # 2. ServerHello
    print("\n2. ServerHello")
    print("   - 选择TLS版本: 1.2")
    print("   - 服务器随机数: 32字节")
    print("   - 选择密码套件: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256")
    
    # 3. Certificate
    print("\n3. Certificate")
    print("   - 服务器证书链")
    print("   - 包含服务器公钥")
    
    # 4. ServerKeyExchange (ECDHE)
    print("\n4. ServerKeyExchange")
    print("   - ECDHE参数")
    print("   - 服务器签名")
    
    # 5. ServerHelloDone
    print("\n5. ServerHelloDone")
    
    # 6. ClientKeyExchange
    print("\n6. ClientKeyExchange")
    print("   - 客户端ECDHE参数")
    print("   - 计算预主密钥")
    
    # 7. ChangeCipherSpec
    print("\n7. ChangeCipherSpec (客户端)")
    print("   - 激活新的密码参数")
    
    # 8. Finished
    print("\n8. Finished (客户端)")
    print("   - 握手消息的MAC验证")
    
    # 9. ChangeCipherSpec
    print("\n9. ChangeCipherSpec (服务器)")
    
    # 10. Finished
    print("\n10. Finished (服务器)")
    print("    - 握手完成")
    
    print("\n=== 握手完成,开始应用数据传输 ===")

def analyze_cipher_suite(cipher_suite_hex):
    """分析密码套件"""
    cipher_suites = {
        0xC02F: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
        0xC030: "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
        0x002F: "TLS_RSA_WITH_AES_128_CBC_SHA",
        0x0035: "TLS_RSA_WITH_AES_256_CBC_SHA",
        0xC013: "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA",
        0xC014: "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
    }
    
    suite_name = cipher_suites.get(cipher_suite_hex, f"Unknown (0x{cipher_suite_hex:04x})")
    
    # 解析密码套件组件
    if "ECDHE" in suite_name:
        key_exchange = "ECDHE (椭圆曲线Diffie-Hellman临时)"
    elif "RSA" in suite_name and "ECDHE" not in suite_name:
        key_exchange = "RSA"
    else:
        key_exchange = "Unknown"
    
    if "AES_128_GCM" in suite_name:
        encryption = "AES-128-GCM"
    elif "AES_256_GCM" in suite_name:
        encryption = "AES-256-GCM"
    elif "AES_128_CBC" in suite_name:
        encryption = "AES-128-CBC"
    elif "AES_256_CBC" in suite_name:
        encryption = "AES-256-CBC"
    else:
        encryption = "Unknown"
    
    if "SHA256" in suite_name:
        mac = "SHA-256"
    elif "SHA384" in suite_name:
        mac = "SHA-384"
    elif "SHA" in suite_name:
        mac = "SHA-1"
    else:
        mac = "AEAD" if "GCM" in suite_name else "Unknown"
    
    return {
        'name': suite_name,
        'key_exchange': key_exchange,
        'encryption': encryption,
        'mac': mac
    }

# 示例使用
if __name__ == "__main__":
    # 演示TLS握手
    demonstrate_tls_handshake()
    
    print("\n" + "="*50)
    
    # 分析密码套件
    cipher_suite = 0xC02F
    analysis = analyze_cipher_suite(cipher_suite)
    
    print(f"\n密码套件分析: 0x{cipher_suite:04x}")
    print(f"名称: {analysis['name']}")
    print(f"密钥交换: {analysis['key_exchange']}")
    print(f"加密算法: {analysis['encryption']}")
    print(f"MAC算法: {analysis['mac']}")
TLS 1.3的改进
客户端 服务器 TLS 1.3 握手 (1-RTT) ClientHello + KeyShare + SupportedGroups 包含密钥共享 ServerHello + KeyShare + EncryptedExtensions + Certificate + CertificateVerify + Finished 立即开始加密 Finished 握手完成,开始应用数据 Application Data (加密) Application Data (加密) 客户端 服务器
TLS安全配置最佳实践
# 文件路径: crypto/tls_security_config.py
import ssl

def create_secure_ssl_context(is_server=False):
    """创建安全的SSL上下文"""
    if is_server:
        context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
    else:
        context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
    
    # 设置最低TLS版本
    context.minimum_version = ssl.TLSVersion.TLSv1_2
    
    # 禁用不安全的协议
    context.options |= ssl.OP_NO_SSLv2
    context.options |= ssl.OP_NO_SSLv3
    context.options |= ssl.OP_NO_TLSv1
    context.options |= ssl.OP_NO_TLSv1_1
    
    # 禁用压缩(防止CRIME攻击)
    context.options |= ssl.OP_NO_COMPRESSION
    
    # 设置安全的密码套件
    secure_ciphers = [
        'ECDHE+AESGCM',
        'ECDHE+CHACHA20',
        'DHE+AESGCM',
        'DHE+CHACHA20',
        '!aNULL',
        '!eNULL',
        '!EXPORT',
        '!DES',
        '!RC4',
        '!MD5',
        '!PSK',
        '!SRP',
        '!CAMELLIA'
    ]
    context.set_ciphers(':'.join(secure_ciphers))
    
    if is_server:
        # 服务器配置
        context.options |= ssl.OP_CIPHER_SERVER_PREFERENCE
        
        # 启用OCSP装订
        context.options |= ssl.OP_TLSEXT_PADDING
        
    else:
        # 客户端配置
        context.check_hostname = True
        context.verify_mode = ssl.CERT_REQUIRED
    
    return context

def analyze_ssl_connection(hostname, port=443):
    """分析SSL连接安全性"""
    context = ssl.create_default_context()
    
    with socket.create_connection((hostname, port)) as sock:
        with context.wrap_socket(sock, server_hostname=hostname) as ssock:
            # 获取连接信息
            cipher = ssock.cipher()
            version = ssock.version()
            cert = ssock.getpeercert()
            
            # 分析安全性
            security_analysis = {
                'protocol_version': version,
                'cipher_suite': cipher[0] if cipher else None,
                'key_exchange': cipher[1] if cipher else None,
                'encryption_strength': cipher[2] if cipher else None,
                'certificate_info': {
                    'subject': cert.get('subject'),
                    'issuer': cert.get('issuer'),
                    'version': cert.get('version'),
                    'serial_number': cert.get('serialNumber'),
                    'not_before': cert.get('notBefore'),
                    'not_after': cert.get('notAfter')
                }
            }
            
            # 安全评估
            security_score = 0
            recommendations = []
            
            # 协议版本评估
            if version == 'TLSv1.3':
                security_score += 30
            elif version == 'TLSv1.2':
                security_score += 25
            else:
                recommendations.append(f"升级到TLS 1.2或更高版本(当前:{version})")
            
            # 密码套件评估
            if cipher and 'GCM' in cipher[0]:
                security_score += 25
            elif cipher and 'CBC' in cipher[0]:
                security_score += 15
                recommendations.append("建议使用AEAD密码套件(如GCM)")
            
            # 密钥长度评估
            if cipher and cipher[2] >= 256:
                security_score += 25
            elif cipher and cipher[2] >= 128:
                security_score += 20
            else:
                recommendations.append("使用更长的加密密钥")
            
            # 证书评估
            if cert:
                security_score += 20
            
            security_analysis['security_score'] = security_score
            security_analysis['recommendations'] = recommendations
            
            return security_analysis

IPSec协议

IPSec(Internet Protocol Security)是网络层安全协议,提供端到端的安全通信。

IPSec架构
IPSec架构
安全协议
安全关联SA
密钥管理
安全策略
AH - 认证头
ESP - 封装安全载荷
安全参数索引SPI
目标地址
安全协议标识
IKE - 互联网密钥交换
手动密钥配置
安全策略数据库SPD
安全关联数据库SAD
IPSec工作模式
# 文件路径: crypto/ipsec_modes.py
import struct
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import hashes, hmac
import os

class IPSecProcessor:
    """IPSec处理器"""
    
    def __init__(self, encryption_key, auth_key):
        self.encryption_key = encryption_key
        self.auth_key = auth_key
    
    def esp_encrypt_transport_mode(self, ip_packet, spi, seq_num):
        """ESP传输模式加密"""
        # 解析IP包
        ip_header = ip_packet[:20]  # 假设标准IP头
        payload = ip_packet[20:]
        
        # 创建ESP头
        esp_header = struct.pack('>II', spi, seq_num)
        
        # 添加填充
        block_size = 16  # AES块大小
        pad_length = block_size - (len(payload) % block_size)
        if pad_length == block_size:
            pad_length = 0
        
        padding = bytes(range(1, pad_length + 1))
        padded_payload = payload + padding + bytes([pad_length])
        
        # 加密载荷
        iv = os.urandom(16)
        cipher = Cipher(algorithms.AES(self.encryption_key), modes.CBC(iv))
        encryptor = cipher.encryptor()
        encrypted_payload = encryptor.update(padded_payload) + encryptor.finalize()
        
        # 构造ESP包
        esp_packet = esp_header + iv + encrypted_payload
        
        # 计算认证数据
        h = hmac.HMAC(self.auth_key, hashes.SHA256())
        h.update(esp_packet)
        auth_data = h.finalize()[:12]  # 截取前12字节
        
        # 构造最终包
        final_packet = ip_header + esp_packet + auth_data
        
        return final_packet
    
    def esp_decrypt_transport_mode(self, esp_packet):
        """ESP传输模式解密"""
        # 解析包结构
        ip_header = esp_packet[:20]
        esp_data = esp_packet[20:-12]
        auth_data = esp_packet[-12:]
        
        # 验证认证数据
        h = hmac.HMAC(self.auth_key, hashes.SHA256())
        h.update(ip_header + esp_data)
        expected_auth = h.finalize()[:12]
        
        if auth_data != expected_auth:
            raise ValueError("ESP认证失败")
        
        # 解析ESP头
        spi, seq_num = struct.unpack('>II', esp_data[:8])
        iv = esp_data[8:24]
        encrypted_payload = esp_data[24:]
        
        # 解密载荷
        cipher = Cipher(algorithms.AES(self.encryption_key), modes.CBC(iv))
        decryptor = cipher.decryptor()
        decrypted_payload = decryptor.update(encrypted_payload) + decryptor.finalize()
        
        # 移除填充
        pad_length = decrypted_payload[-1]
        original_payload = decrypted_payload[:-(pad_length + 1)]
        
        # 重构原始IP包
        original_packet = ip_header + original_payload
        
        return original_packet, spi, seq_num
    
    def esp_encrypt_tunnel_mode(self, ip_packet, spi, seq_num, tunnel_src, tunnel_dst):
        """ESP隧道模式加密"""
        # 创建新的IP头(隧道头)
        tunnel_ip_header = self.create_ip_header(tunnel_src, tunnel_dst, len(ip_packet))
        
        # 创建ESP头
        esp_header = struct.pack('>II', spi, seq_num)
        
        # 添加填充
        block_size = 16
        pad_length = block_size - (len(ip_packet) % block_size)
        if pad_length == block_size:
            pad_length = 0
        
        padding = bytes(range(1, pad_length + 1))
        padded_payload = ip_packet + padding + bytes([pad_length])
        
        # 加密整个原始IP包
        iv = os.urandom(16)
        cipher = Cipher(algorithms.AES(self.encryption_key), modes.CBC(iv))
        encryptor = cipher.encryptor()
        encrypted_payload = encryptor.update(padded_payload) + encryptor.finalize()
        
        # 构造ESP包
        esp_packet = esp_header + iv + encrypted_payload
        
        # 计算认证数据
        h = hmac.HMAC(self.auth_key, hashes.SHA256())
        h.update(esp_packet)
        auth_data = h.finalize()[:12]
        
        # 构造最终隧道包
        tunnel_packet = tunnel_ip_header + esp_packet + auth_data
        
        return tunnel_packet
    
    def create_ip_header(self, src_ip, dst_ip, payload_length):
        """创建IP头"""
        # 简化的IP头创建
        version_ihl = 0x45  # IPv4, 20字节头长度
        tos = 0
        total_length = 20 + payload_length
        identification = 0
        flags_fragment = 0
        ttl = 64
        protocol = 50  # ESP协议号
        checksum = 0  # 简化,实际需要计算
        
        # 转换IP地址
        src_bytes = bytes(map(int, src_ip.split('.')))
        dst_bytes = bytes(map(int, dst_ip.split('.')))
        
        ip_header = struct.pack('>BBHHHBBH4s4s',
                               version_ihl, tos, total_length,
                               identification, flags_fragment,
                               ttl, protocol, checksum,
                               src_bytes, dst_bytes)
        
        return ip_header

def demonstrate_ipsec_modes():
    """演示IPSec工作模式"""
    # 生成密钥
    encryption_key = os.urandom(32)  # AES-256
    auth_key = os.urandom(32)        # HMAC-SHA256
    
    processor = IPSecProcessor(encryption_key, auth_key)
    
    # 模拟原始IP包
    original_packet = b'\x45\x00\x00\x54' + b'\x00' * 16 + b'Hello, IPSec!'
    
    print("=== IPSec模式演示 ===")
    print(f"原始包长度: {len(original_packet)} 字节")
    
    # 传输模式
    print("\n1. ESP传输模式:")
    encrypted_transport = processor.esp_encrypt_transport_mode(
        original_packet, spi=0x12345678, seq_num=1
    )
    print(f"   加密后长度: {len(encrypted_transport)} 字节")
    
    decrypted_transport, spi, seq = processor.esp_decrypt_transport_mode(encrypted_transport)
    print(f"   解密后长度: {len(decrypted_transport)} 字节")
    print(f"   SPI: 0x{spi:08x}, 序列号: {seq}")
    
    # 隧道模式
    print("\n2. ESP隧道模式:")
    encrypted_tunnel = processor.esp_encrypt_tunnel_mode(
        original_packet, spi=0x87654321, seq_num=2,
        tunnel_src="192.168.1.1", tunnel_dst="10.0.0.1"
    )
    print(f"   隧道包长度: {len(encrypted_tunnel)} 字节")

SSH协议

SSH(Secure Shell)是应用层安全协议,主要用于远程登录和文件传输。

SSH协议架构
SSH协议栈
SSH传输层协议
SSH用户认证协议
SSH连接协议
服务器认证
密钥交换
加密算法协商
MAC算法协商
密码认证
公钥认证
主机认证
键盘交互认证
通道复用
端口转发
X11转发
文件传输
SSH密钥交换过程
# 文件路径: crypto/ssh_protocol.py
import hashlib
import struct
from cryptography.hazmat.primitives.asymmetric import rsa, dsa
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
import base64

class SSHKeyExchange:
    """SSH密钥交换实现"""
    
    def __init__(self):
        self.client_version = "SSH-2.0-OpenSSH_8.0"
        self.server_version = "SSH-2.0-OpenSSH_8.0"
        self.client_kexinit = None
        self.server_kexinit = None
        self.shared_secret = None
        self.exchange_hash = None
    
    def create_kexinit_packet(self, is_server=False):
        """创建密钥交换初始化包"""
        # 支持的算法列表
        kex_algorithms = [
            "diffie-hellman-group14-sha256",
            "ecdh-sha2-nistp256",
            "ecdh-sha2-nistp384"
        ]
        
        server_host_key_algorithms = [
            "rsa-sha2-512",
            "rsa-sha2-256",
            "ssh-rsa",
            "ecdsa-sha2-nistp256"
        ]
        
        encryption_algorithms = [
            "aes128-ctr",
            "aes192-ctr", 
            "aes256-ctr",
            "aes128-gcm@openssh.com",
            "aes256-gcm@openssh.com"
        ]
        
        mac_algorithms = [
            "hmac-sha2-256",
            "hmac-sha2-512",
            "hmac-sha1"
        ]
        
        compression_algorithms = [
            "none",
            "zlib@openssh.com"
        ]
        
        # 构造KEXINIT包
        kexinit_data = {
            'kex_algorithms': kex_algorithms,
            'server_host_key_algorithms': server_host_key_algorithms,
            'encryption_algorithms_client_to_server': encryption_algorithms,
            'encryption_algorithms_server_to_client': encryption_algorithms,
            'mac_algorithms_client_to_server': mac_algorithms,
            'mac_algorithms_server_to_client': mac_algorithms,
            'compression_algorithms_client_to_server': compression_algorithms,
            'compression_algorithms_server_to_client': compression_algorithms
        }
        
        if is_server:
            self.server_kexinit = kexinit_data
        else:
            self.client_kexinit = kexinit_data
        
        return kexinit_data
    
    def perform_dh_key_exchange(self, p, g, server_private_key=None):
        """执行Diffie-Hellman密钥交换"""
        import random
        
        # 生成客户端私钥
        client_private = random.randint(2, p-2)
        client_public = pow(g, client_private, p)
        
        if server_private_key is None:
            # 生成服务器私钥
            server_private = random.randint(2, p-2)
        else:
            server_private = server_private_key
        
        server_public = pow(g, server_private, p)
        
        # 计算共享密钥
        shared_secret_client = pow(server_public, client_private, p)
        shared_secret_server = pow(client_public, server_private, p)
        
        assert shared_secret_client == shared_secret_server
        
        self.shared_secret = shared_secret_client
        
        return {
            'client_public': client_public,
            'server_public': server_public,
            'shared_secret': shared_secret_client
        }
    
    def compute_exchange_hash(self, client_public, server_public, server_host_key):
        """计算交换哈希"""
        # SSH交换哈希计算
        hash_data = b''
        
        # 添加版本字符串
        hash_data += self._ssh_string(self.client_version.encode())
        hash_data += self._ssh_string(self.server_version.encode())
        
        # 添加KEXINIT数据(简化)
        hash_data += self._ssh_string(str(self.client_kexinit).encode())
        hash_data += self._ssh_string(str(self.server_kexinit).encode())
        
        # 添加服务器主机密钥
        hash_data += self._ssh_string(server_host_key)
        
        # 添加DH公钥
        hash_data += self._ssh_mpint(client_public)
        hash_data += self._ssh_mpint(server_public)
        
        # 添加共享密钥
        hash_data += self._ssh_mpint(self.shared_secret)
        
        # 计算SHA-256哈希
        self.exchange_hash = hashlib.sha256(hash_data).digest()
        
        return self.exchange_hash
    
    def derive_keys(self, shared_secret, exchange_hash, session_id):
        """派生会话密钥"""
        def derive_key(shared_secret, exchange_hash, session_id, key_id, key_length):
            """派生单个密钥"""
            hash_data = self._ssh_mpint(shared_secret) + exchange_hash + key_id + session_id
            key = hashlib.sha256(hash_data).digest()
            
            # 如果需要更长的密钥,继续哈希
            while len(key) < key_length:
                hash_data = self._ssh_mpint(shared_secret) + exchange_hash + key
                key += hashlib.sha256(hash_data).digest()
            
            return key[:key_length]
        
        # 派生各种密钥
        keys = {
            'client_to_server_iv': derive_key(shared_secret, exchange_hash, session_id, b'A', 16),
            'server_to_client_iv': derive_key(shared_secret, exchange_hash, session_id, b'B', 16),
            'client_to_server_encryption': derive_key(shared_secret, exchange_hash, session_id, b'C', 32),
            'server_to_client_encryption': derive_key(shared_secret, exchange_hash, session_id, b'D', 32),
            'client_to_server_mac': derive_key(shared_secret, exchange_hash, session_id, b'E', 32),
            'server_to_client_mac': derive_key(shared_secret, exchange_hash, session_id, b'F', 32)
        }
        
        return keys
    
    def _ssh_string(self, data):
        """SSH字符串编码"""
        return struct.pack('>I', len(data)) + data
    
    def _ssh_mpint(self, number):
        """SSH多精度整数编码"""
        if number == 0:
            return struct.pack('>I', 0)
        
        # 转换为字节
        byte_length = (number.bit_length() + 7) // 8
        bytes_data = number.to_bytes(byte_length, 'big')
        
        # 如果最高位是1,需要添加0x00前缀
        if bytes_data[0] & 0x80:
            bytes_data = b'\x00' + bytes_data
        
        return struct.pack('>I', len(bytes_data)) + bytes_data

def demonstrate_ssh_handshake():
    """演示SSH握手过程"""
    print("=== SSH握手过程演示 ===")
    
    ssh_kex = SSHKeyExchange()
    
    # 1. 版本交换
    print("1. 版本交换")
    print(f"   客户端: {ssh_kex.client_version}")
    print(f"   服务器: {ssh_kex.server_version}")
    
    # 2. 算法协商
    print("\n2. 算法协商 (KEXINIT)")
    client_kexinit = ssh_kex.create_kexinit_packet(is_server=False)
    server_kexinit = ssh_kex.create_kexinit_packet(is_server=True)
    
    print("   支持的密钥交换算法:")
    for alg in client_kexinit['kex_algorithms'][:3]:
        print(f"     - {alg}")
    
    # 3. 密钥交换
    print("\n3. Diffie-Hellman密钥交换")
    
    # 使用RFC 3526 Group 14参数
    p = int("FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
            "29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
            "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
            "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
            "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
            "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
            "83655D23DCA3AD961C62F356208552BB9ED529077096966D"
            "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
            "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
            "DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
            "15728E5A8AACAA68FFFFFFFFFFFFFFFF", 16)
    g = 2
    
    dh_result = ssh_kex.perform_dh_key_exchange(p, g)
    print(f"   共享密钥已生成 (长度: {dh_result['shared_secret'].bit_length()} 位)")
    
    # 4. 服务器认证
    print("\n4. 服务器主机密钥验证")
    
    # 生成模拟的服务器密钥
    server_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
    server_public_key_bytes = server_key.public_key().public_bytes(
        encoding=serialization.Encoding.OpenSSH,
        format=serialization.PublicFormat.OpenSSH
    )
    
    # 计算交换哈希
    exchange_hash = ssh_kex.compute_exchange_hash(
        dh_result['client_public'],
        dh_result['server_public'],
        server_public_key_bytes
    )
    
    print(f"   交换哈希: {exchange_hash.hex()[:32]}...")
    
    # 5. 密钥派生
    print("\n5. 会话密钥派生")
    session_keys = ssh_kex.derive_keys(
        dh_result['shared_secret'],
        exchange_hash,
        exchange_hash  # 第一次连接时session_id = exchange_hash
    )
    
    print("   派生的密钥:")
    for key_name, key_value in session_keys.items():
        print(f"     {key_name}: {key_value.hex()[:16]}...")
    
    print("\n=== SSH握手完成 ===")

# 示例使用
if __name__ == "__main__":
    demonstrate_ssh_handshake()

无线网络安全协议

WPA/WPA2/WPA3演进
无线安全协议演进
WEP
WPA
WPA2
WPA3
RC4加密
静态密钥
已被破解
TKIP
动态密钥
MIC保护
AES-CCMP
强认证
广泛部署
SAE认证
增强加密
前向保密
WPA2四次握手
# 文件路径: crypto/wpa2_handshake.py
import hashlib
import hmac
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
import os

class WPA2HandshakeProcessor:
    """WPA2四次握手处理器"""
    
    def __init__(self, ssid, passphrase):
        self.ssid = ssid
        self.passphrase = passphrase
        self.pmk = self.derive_pmk()
        self.ptk = None
        self.gtk = None
    
    def derive_pmk(self):
        """派生预共享主密钥PMK"""
        # 使用PBKDF2派生PMK
        kdf = PBKDF2HMAC(
            algorithm=hashes.SHA1(),
            length=32,  # PMK长度为256位
            salt=self.ssid.encode(),
            iterations=4096
        )
        pmk = kdf.derive(self.passphrase.encode())
        return pmk
    
    def derive_ptk(self, ap_mac, sta_mac, anonce, snonce):
        """派生成对临时密钥PTK"""
        # PTK = PRF-512(PMK, "Pairwise key expansion", 
        #               Min(AP_MAC, STA_MAC) || Max(AP_MAC, STA_MAC) ||
        #               Min(ANonce, SNonce) || Max(ANonce, SNonce))
        
        # 确定MAC地址顺序
        if ap_mac < sta_mac:
            mac_data = ap_mac + sta_mac
        else:
            mac_data = sta_mac + ap_mac
        
        # 确定Nonce顺序
        if anonce < snonce:
            nonce_data = anonce + snonce
        else:
            nonce_data = snonce + anonce
        
        # 构造PRF输入
        prf_input = b"Pairwise key expansion\x00" + mac_data + nonce_data
        
        # 使用PRF-512生成PTK
        ptk = self.prf_512(self.pmk, prf_input)
        
        # PTK分解
        self.ptk = {
            'kck': ptk[0:16],   # 密钥确认密钥
            'kek': ptk[16:32],  # 密钥加密密钥
            'tk': ptk[32:48],   # 临时密钥
            'mic_key': ptk[48:64]  # MIC密钥
        }
        
        return self.ptk
    
    def prf_512(self, key, data):
        """伪随机函数PRF-512"""
        result = b''
        i = 0
        
        while len(result) < 64:  # 512位 = 64字节
            h = hmac.new(key, data + bytes([i]), hashlib.sha1)
            result += h.digest()
            i += 1
        
        return result[:64]
    
    def calculate_mic(self, eapol_frame, key_type='ptk'):
        """计算MIC"""
        if key_type == 'ptk' and self.ptk:
            mic_key = self.ptk['kck']
        else:
            raise ValueError("PTK未生成或密钥类型错误")
        
        # 将MIC字段清零
        frame_copy = bytearray(eapol_frame)
        # 假设MIC字段在特定位置(实际需要根据EAPOL格式解析)
        mic_offset = len(frame_copy) - 16
        frame_copy[mic_offset:mic_offset+16] = b'\x00' * 16
        
        # 计算HMAC-MD5
        h = hmac.new(mic_key, bytes(frame_copy), hashlib.md5)
        return h.digest()
    
    def verify_mic(self, eapol_frame, received_mic):
        """验证MIC"""
        calculated_mic = self.calculate_mic(eapol_frame)
        return calculated_mic == received_mic

def demonstrate_wpa2_handshake():
    """演示WPA2四次握手"""
    print("=== WPA2四次握手演示 ===")
    
    # 网络参数
    ssid = "TestNetwork"
    passphrase = "SecurePassword123"
    ap_mac = bytes.fromhex("001122334455")
    sta_mac = bytes.fromhex("aabbccddeeff")
    
    # 创建处理器
    wpa2 = WPA2HandshakeProcessor(ssid, passphrase)
    
    print(f"网络SSID: {ssid}")
    print(f"预共享密钥: {passphrase}")
    print(f"PMK: {wpa2.pmk.hex()}")
    
    # 生成随机数
    anonce = os.urandom(32)  # AP随机数
    snonce = os.urandom(32)  # STA随机数
    
    print(f"\nAP随机数: {anonce.hex()[:32]}...")
    print(f"STA随机数: {snonce.hex()[:32]}...")
    
    # 派生PTK
    ptk = wpa2.derive_ptk(ap_mac, sta_mac, anonce, snonce)
    
    print(f"\n派生的PTK组件:")
    print(f"KCK (密钥确认密钥): {ptk['kck'].hex()}")
    print(f"KEK (密钥加密密钥): {ptk['kek'].hex()}")
    print(f"TK (临时密钥): {ptk['tk'].hex()}")
    
    # 模拟四次握手过程
    print(f"\n=== 四次握手过程 ===")
    
    print("1. AP -> STA: EAPOL-Key (ANonce)")
    print("   - 包含AP随机数")
    print("   - 启动握手过程")
    
    print("\n2. STA -> AP: EAPOL-Key (SNonce + MIC)")
    print("   - 包含STA随机数")
    print("   - 包含MIC验证")
    print("   - STA已计算PTK")
    
    print("\n3. AP -> STA: EAPOL-Key (GTK + MIC)")
    print("   - 安装PTK")
    print("   - 传输组临时密钥GTK")
    print("   - 包含MIC验证")
    
    print("\n4. STA -> AP: EAPOL-Key (确认)")
    print("   - 确认密钥安装")
    print("   - 握手完成")
    
    print(f"\n=== 握手完成,开始数据传输 ===")

# WPA3 SAE认证
class WPA3SAEProcessor:
    """WPA3 SAE (Simultaneous Authentication of Equals) 处理器"""
    
    def __init__(self, password):
        self.password = password
        self.pwe = None  # Password Element
        self.pmk = None
    
    def derive_pwe(self, mac1, mac2, ssid):
        """派生密码元素PWE"""
        # SAE使用椭圆曲线或有限域群
        # 这里简化实现概念
        
        # 构造标识符
        identifier = mac1 + mac2 + ssid.encode()
        
        # 使用密码和标识符派生PWE
        # 实际实现需要使用特定的椭圆曲线算法
        hash_input = self.password.encode() + identifier
        self.pwe = hashlib.sha256(hash_input).digest()
        
        return self.pwe
    
    def sae_commit(self, mac1, mac2, ssid):
        """SAE Commit阶段"""
        # 派生PWE
        pwe = self.derive_pwe(mac1, mac2, ssid)
        
        # 生成随机标量和元素
        scalar = os.urandom(32)
        element = os.urandom(32)  # 简化表示
        
        return {
            'scalar': scalar,
            'element': element,
            'pwe': pwe
        }
    
    def sae_confirm(self, commit_data, peer_commit):
        """SAE Confirm阶段"""
        # 计算确认值
        confirm_input = (commit_data['scalar'] + 
                        commit_data['element'] + 
                        peer_commit['scalar'] + 
                        peer_commit['element'])
        
        confirm = hmac.new(self.pwe, confirm_input, hashlib.sha256).digest()
        
        return confirm

def demonstrate_wpa3_sae():
    """演示WPA3 SAE认证"""
    print("\n=== WPA3 SAE认证演示 ===")
    
    password = "SecureWPA3Password"
    ssid = "WPA3Network"
    
    # 设备MAC地址
    ap_mac = bytes.fromhex("001122334455")
    sta_mac = bytes.fromhex("aabbccddeeff")
    
    # 创建SAE处理器
    ap_sae = WPA3SAEProcessor(password)
    sta_sae = WPA3SAEProcessor(password)
    
    print(f"网络: {ssid}")
    print(f"密码: {password}")
    
    # SAE Commit阶段
    print(f"\n1. SAE Commit阶段")
    ap_commit = ap_sae.sae_commit(ap_mac, sta_mac, ssid)
    sta_commit = sta_sae.sae_commit(sta_mac, ap_mac, ssid)
    
    print(f"   AP Commit: {ap_commit['scalar'].hex()[:16]}...")
    print(f"   STA Commit: {sta_commit['scalar'].hex()[:16]}...")
    
    # SAE Confirm阶段
    print(f"\n2. SAE Confirm阶段")
    ap_confirm = ap_sae.sae_confirm(ap_commit, sta_commit)
    sta_confirm = sta_sae.sae_confirm(sta_commit, ap_commit)
    
    print(f"   AP Confirm: {ap_confirm.hex()[:16]}...")
    print(f"   STA Confirm: {sta_confirm.hex()[:16]}...")
    
    print(f"\n=== SAE认证完成 ===")

# 示例使用
if __name__ == "__main__":
    demonstrate_wpa2_handshake()
    demonstrate_wpa3_sae()

实践练习

练习1:TLS协议分析

任务:分析真实的TLS握手过程

  • 使用Wireshark捕获TLS握手包
  • 分析密码套件选择和证书验证
  • 识别可能的安全问题

验收标准:能够完整分析TLS握手的每个步骤。

练习2:IPSec VPN配置

任务:配置IPSec VPN隧道

  • 设置IKE参数和安全策略
  • 配置ESP隧道模式
  • 测试连通性和安全性

验收标准:成功建立安全的VPN连接。

练习3:无线网络安全评估

任务:评估无线网络安全配置

  • 分析WPA2/WPA3配置
  • 检测常见安全漏洞
  • 提出安全改进建议

验收标准:提供完整的安全评估报告。

常见问题(FAQ)

Q1:TLS 1.2和TLS 1.3有什么主要区别?
A:主要区别:

  • 握手轮次:TLS 1.3只需1-RTT,TLS 1.2需要2-RTT
  • 加密算法:TLS 1.3移除了不安全的算法
  • 前向保密:TLS 1.3强制使用前向保密
  • 握手加密:TLS 1.3对握手消息进行加密

Q2:如何选择合适的IPSec模式?
A:选择标准:

  • 传输模式:端到端通信,保护上层协议
  • 隧道模式:网关到网关,完整IP包保护
  • AH协议:只需要认证,不需要加密
  • ESP协议:需要认证和加密

Q3:SSH密钥认证比密码认证安全在哪里?
A:优势包括:

  • 抗暴力破解:私钥长度远超密码复杂度
  • 无网络传输:私钥不在网络上传输
  • 可撤销性:可以单独撤销公钥
  • 审计能力:可以追踪密钥使用

Q4:WPA3相比WPA2有哪些改进?
A:主要改进:

  • SAE认证:抗离线字典攻击
  • 前向保密:历史数据保护
  • 增强加密:192位安全级别
  • 简化配置:Wi-Fi Easy Connect

总结

本章详细介绍了网络安全协议,主要包括:

  • 协议分层:不同层次的安全协议及其作用
  • SSL/TLS:传输层安全协议的握手和加密机制
  • IPSec:网络层安全协议的架构和工作模式
  • SSH协议:安全远程访问协议的认证和加密
  • 无线安全:WPA/WPA2/WPA3的演进和安全机制

网络安全协议是构建安全通信的基础,理解其原理对于网络安全至关重要。

下一步

参考与引用

更新记录

  • 更新时间: 2024-01-20 | 更新内容: 创建网络安全协议章节,包含SSL/TLS、IPSec、SSH、无线安全等详细内容 | 更新人: Assistant
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值