HTTPS

发布于:2025-08-29 ⋅ 阅读:(18) ⋅ 点赞:(0)



1. HTTPS 核心概念

1.1 什么是HTTPS?

HTTPS = HTTP + SSL/TLS,是在HTTP协议基础上加入安全层的加密通信协议。

特性 HTTP HTTPS
协议 应用层协议 应用层+安全层协议
端口 80 443
加密 明文传输 加密传输
安全性 身份验证+数据加密
性能 稍慢(加密开销)

1.2 HTTPS 核心价值

  1. 机密性 - 防止窃听(加密传输)
  2. 完整性 - 防止篡改(数字签名)
  3. 身份认证 - 防止冒充(证书验证)

2. HTTPS 工作原理

2.1 TLS握手过程

Client Server Certificate Authority ClientHello (支持的加密套件) ServerHello (选择的加密套件) Server Certificate (公钥证书) 证书包含公钥和CA签名 验证证书有效性 验证结果 PreMasterSecret (用服务器公钥加密) 交换完成,使用对称加密通信 基于PreMasterSecret生成会话密钥 加密的HTTP请求 加密的HTTP响应 Client Server Certificate Authority

2.2 加密层次结构

HTTP应用数据
TLS记录层加密
TCP传输层
IP网络层
对称加密算法
会话密钥
非对称加密

3. TLS握手详细过程

3.1 C代码实现握手关键步骤

/**
 * TLS 1.3握手过程模拟实现
 * 简化版代码展示核心逻辑
 */

#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/x509_vfy.h>

#define TLS_VERSION TLS1_3_VERSION

typedef struct {
    SSL_CTX *ctx;
    SSL *ssl;
    X509 *server_cert;
    EVP_PKEY *server_key;
} tls_context;

// 初始化TLS上下文
int tls_context_init(tls_context *tls_ctx) {
    // 1. 创建SSL上下文
    tls_ctx->ctx = SSL_CTX_new(TLS_method());
    if (!tls_ctx->ctx) return -1;
    
    // 2. 配置TLS版本
    SSL_CTX_set_min_proto_version(tls_ctx->ctx, TLS_VERSION);
    SSL_CTX_set_max_proto_version(tls_ctx->ctx, TLS_VERSION);
    
    return 0;
}

// 服务器配置证书
int tls_server_setup(tls_context *tls_ctx, 
                    const char *cert_file, 
                    const char *key_file) {
    // 1. 加载证书链
    if (SSL_CTX_use_certificate_file(tls_ctx->ctx, cert_file, SSL_FILETYPE_PEM) <= 0) {
        return -1;
    }
    
    // 2. 加载私钥
    if (SSL_CTX_use_PrivateKey_file(tls_ctx->ctx, key_file, SSL_FILETYPE_PEM) <= 0) {
        return -1;
    }
    
    // 3. 验证证书和私钥匹配
    if (!SSL_CTX_check_private_key(tls_ctx->ctx)) {
        return -1;
    }
    
    return 0;
}

// 客户端验证服务器证书
int verify_server_certificate(SSL *ssl, const char *hostname) {
    X509 *cert = SSL_get_peer_certificate(ssl);
    if (!cert) {
        return -1; // 无证书
    }
    
    // 检查证书有效期
    if (X509_cmp_current_time(X509_get_notBefore(cert)) > 0 ||
        X509_cmp_current_time(X509_get_notAfter(cert)) < 0) {
        X509_free(cert);
        return -1; // 证书过期或未生效
    }
    
    // 验证主机名(SNI)
    if (X509_check_host(cert, hostname, strlen(hostname), 0, NULL) != 1) {
        X509_free(cert);
        return -1; // 主机名不匹配
    }
    
    X509_free(cert);
    return 0;
}

// 完整的TLS握手过程
int tls_handshake(SSL *ssl, int is_server) {
    int ret;
    
    if (is_server) {
        ret = SSL_accept(ssl); // 服务器端握手
    } else {
        ret = SSL_connect(ssl); // 客户端握手
    }
    
    if (ret != 1) {
        int err = SSL_get_error(ssl, ret);
        printf("TLS handshake failed: %d\n", err);
        return -1;
    }
    
    printf("TLS handshake successful\n");
    printf("Protocol: %s\n", SSL_get_version(ssl));
    printf("Cipher: %s\n", SSL_get_cipher(ssl));
    
    return 0;
}

3.2 密钥交换过程

/**
 * 密钥交换和会话密钥生成
 */

// 生成预主密钥
int generate_pre_master_secret(unsigned char *pms, size_t *pms_len) {
    // 生成48字节的随机预主密钥
    if (RAND_bytes(pms, 48) != 1) {
        return -1;
    }
    *pms_len = 48;
    return 0;
}

// 使用服务器公钥加密预主密钥
int encrypt_pre_master_secret(EVP_PKEY *pubkey, 
                             const unsigned char *pms, 
                             size_t pms_len,
                             unsigned char *encrypted, 
                             size_t *encrypted_len) {
    EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pubkey, NULL);
    if (!ctx) return -1;
    
    if (EVP_PKEY_encrypt_init(ctx) <= 0) {
        EVP_PKEY_CTX_free(ctx);
        return -1;
    }
    
    if (EVP_PKEY_encrypt(ctx, encrypted, encrypted_len, pms, pms_len) <= 0) {
        EVP_PKEY_CTX_free(ctx);
        return -1;
    }
    
    EVP_PKEY_CTX_free(ctx);
    return 0;
}

// 生成会话密钥
int derive_session_keys(const unsigned char *pms, 
                       size_t pms_len,
                       const unsigned char *client_random,
                       const unsigned char *server_random,
                       unsigned char *client_key,
                       unsigned char *server_key) {
    // 使用HKDF或类似算法从预主密钥生成会话密钥
    // 这里使用简化的伪代码表示
    
    unsigned char key_material[64];
    HMAC(EVP_sha256(), pms, pms_len, client_random, 32, key_material, NULL);
    HMAC(EVP_sha256(), key_material, 32, server_random, 32, key_material + 32, NULL);
    
    memcpy(client_key, key_material, 32);
    memcpy(server_key, key_material + 32, 32);
    
    return 0;
}

4. 证书体系

4.1 证书格式和验证

/**
 * X.509证书处理
 */

typedef struct {
    X509 *cert;
    EVP_PKEY *key;
    STACK_OF(X509) *chain;
} certificate_bundle;

// 加载证书文件
int load_certificate(const char *cert_file, const char *key_file, 
                    certificate_bundle *bundle) {
    FILE *fp = fopen(cert_file, "r");
    if (!fp) return -1;
    
    bundle->cert = PEM_read_X509(fp, NULL, NULL, NULL);
    fclose(fp);
    
    if (!bundle->cert) return -1;
    
    fp = fopen(key_file, "r");
    if (!fp) {
        X509_free(bundle->cert);
        return -1;
    }
    
    bundle->key = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
    fclose(fp);
    
    if (!bundle->key) {
        X509_free(bundle->cert);
        return -1;
    }
    
    return 0;
}

// 证书验证回调
int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) {
    if (!preverify_ok) {
        int err = X509_STORE_CTX_get_error(ctx);
        printf("Certificate verification error: %s\n", 
               X509_verify_cert_error_string(err));
        return 0;
    }
    
    // 额外的验证逻辑
    X509 *cert = X509_STORE_CTX_get_current_cert(ctx);
    int depth = X509_STORE_CTX_get_error_depth(ctx);
    
    printf("Certificate verified successfully (depth: %d)\n", depth);
    return 1;
}

4.2 证书链验证

终端实体证书
中间CA证书
根CA证书
信任锚
证书验证过程
验证签名链
检查有效期
验证密钥用法
检查CRL/OCSP

5. 嵌入式HTTPS实现

5.1 资源优化配置

/**
 * 嵌入式TLS配置优化
 */

// 内存池配置
#define MBEDTLS_MEMORY_BUFFER_ALLOC_C
#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4

static unsigned char memory_buf[1024 * 16]; // 16KB内存池

void init_embedded_tls(void) {
    // 初始化内存分配器
    mbedtls_memory_buffer_alloc_init(memory_buf, sizeof(memory_buf));
    
    // 精简密码套件列表
    static const int ciphersuites[] = {
        MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
        MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
        0 // 结束标记
    };
    
    mbedtls_ssl_conf_ciphersuites(&conf, ciphersuites);
}

// 精简功能配置
void configure_minimal_tls(void) {
    // 禁用不必要的功能节省资源
    mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
    
    // 设置会话缓存减少握手开销
    mbedtls_ssl_conf_session_cache(&conf, &cache,
                                  mbedtls_ssl_cache_get,
                                  mbedtls_ssl_cache_set);
}

5.2 性能优化策略

/**
 * 嵌入式HTTPS性能优化
 */

// 会话恢复减少握手开销
typedef struct {
    unsigned char session_id[32];
    time_t timestamp;
    unsigned char master_secret[48];
} tls_session_cache;

// 预计算优化
int precompute_handshake_params(SSL_CTX *ctx) {
    // 预计算ECDH参数
    EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
    if (!ecdh) return -1;
    
    EC_KEY_generate_key(ecdh);
    SSL_CTX_set_tmp_ecdh(ctx, ecdh);
    EC_KEY_free(ecdh);
    
    return 0;
}

// 零拷贝发送优化
int ssl_send_zero_copy(SSL *ssl, const void *buf, size_t len) {
    // 尝试零拷贝发送
    int sent = SSL_send(ssl, buf, len, SSL_ZERO_COPY);
    if (sent > 0) {
        return sent;
    }
    
    // 回退到普通发送
    return SSL_write(ssl, buf, len);
}

6. 安全最佳实践

6.1 安全配置

/**
 * TLS安全配置
 */

void configure_security_settings(SSL_CTX *ctx) {
    // 1. 禁用不安全协议
    SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
    
    // 2. 启用完美前向保密
    SSL_CTX_set_ecdh_auto(ctx, 1);
    
    // 3. 配置密码套件优先级
    SSL_CTX_set_cipher_list(ctx, "ECDHE-ECDSA-AES128-GCM-SHA256:"
                           "ECDHE-RSA-AES128-GCM-SHA256:");
    
    // 4. 启用HSTS等安全头
    enable_hsts(ctx);
}

// 证书钉扎
int certificate_pinning(X509 *cert, const unsigned char *expected_fingerprint) {
    unsigned char fingerprint[EVP_MAX_MD_SIZE];
    unsigned int len;
    
    if (!X509_digest(cert, EVP_sha256(), fingerprint, &len)) {
        return -1;
    }
    
    if (memcmp(fingerprint, expected_fingerprint, len) != 0) {
        return -1; // 证书指纹不匹配
    }
    
    return 0;
}

6.2 攻击防护

/**
 * 常见攻击防护
 */

// 防止BEAST攻击
void prevent_beast_attack(SSL_CTX *ctx) {
    SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION | SSL_OP_CIPHER_SERVER_PREFERENCE);
}

// 防止重放攻击
int check_replay_attack(const unsigned char *client_random, 
                       time_t timestamp) {
    // 检查时间戳有效性
    time_t now = time(NULL);
    if (labs(now - timestamp) > 300) { // 5分钟窗口
        return -1;
    }
    
    // 检查随机数是否重复使用
    if (is_random_used(client_random)) {
        return -1;
    }
    
    return 0;
}

7. 完整HTTPS客户端示例

/**
 * 嵌入式HTTPS客户端完整示例
 */

#include <openssl/ssl.h>
#include <netinet/in.h>
#include <sys/socket.h>

int https_client_request(const char *hostname, const char *path) {
    int sockfd;
    SSL_CTX *ctx;
    SSL *ssl;
    
    // 1. 创建TCP连接
    sockfd = create_tcp_connection(hostname, 443);
    if (sockfd < 0) return -1;
    
    // 2. 初始化SSL上下文
    ctx = SSL_CTX_new(TLS_client_method());
    if (!ctx) {
        close(sockfd);
        return -1;
    }
    
    // 3. 配置SSL
    configure_security_settings(ctx);
    
    // 4. 创建SSL连接
    ssl = SSL_new(ctx);
    SSL_set_fd(ssl, sockfd);
    
    // 5. 设置SNI
    SSL_set_tlsext_host_name(ssl, hostname);
    
    // 6. TLS握手
    if (SSL_connect(ssl) != 1) {
        SSL_free(ssl);
        SSL_CTX_free(ctx);
        close(sockfd);
        return -1;
    }
    
    // 7. 发送HTTPS请求
    char request[512];
    snprintf(request, sizeof(request),
             "GET %s HTTP/1.1\r\n"
             "Host: %s\r\n"
             "Connection: close\r\n"
             "\r\n", path, hostname);
    
    SSL_write(ssl, request, strlen(request));
    
    // 8. 读取响应
    char response[1024];
    int bytes_read;
    while ((bytes_read = SSL_read(ssl, response, sizeof(response) - 1)) > 0) {
        response[bytes_read] = '\0';
        printf("%s", response);
    }
    
    // 9. 清理资源
    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    close(sockfd);
    
    return 0;
}

8. 性能监控和调试

8.1 性能统计

/**
 * TLS性能监控
 */

typedef struct {
    uint32_t handshake_time;
    uint32_t data_transferred;
    uint32_t encryption_time;
    uint32_t decryption_time;
} tls_performance_stats;

void monitor_tls_performance(SSL *ssl, tls_performance_stats *stats) {
    // 获取握手时间
    stats->handshake_time = SSL_get_handshake_time(ssl);
    
    // 获取传输数据量
    stats->data_transferred = SSL_get_total_transferred(ssl);
}

8.2 调试支持

/**
 * TLS调试工具
 */

void ssl_debug_callback(const SSL *ssl, int where, int ret) {
    const char *str;
    int w = where & ~SSL_ST_MASK;
    
    if (w & SSL_ST_CONNECT) str = "SSL_connect";
    else if (w & SSL_ST_ACCEPT) str = "SSL_accept";
    else str = "undefined";
    
    if (where & SSL_CB_LOOP) {
        printf("%s: %s\n", str, SSL_state_string_long(ssl));
    } else if (where & SSL_CB_ALERT) {
        printf("SSL alert: %s\n", SSL_alert_type_string_long(ret));
    }
}

// 启用调试
void enable_ssl_debug(SSL_CTX *ctx) {
    SSL_CTX_set_info_callback(ctx, ssl_debug_callback);
    SSL_CTX_set_msg_callback(ctx, ssl_msg_callback);
}

9. 总结

HTTPS在嵌入式系统中的实现需要考虑以下关键点:

方面 推荐方案 注意事项
内存使用 静态分配+内存池 避免动态内存碎片
性能优化 会话恢复+预计算 平衡安全性和性能
证书管理 证书钉扎+精简信任链 减少存储空间占用
安全配置 完美前向保密+现代密码套件 禁用过时协议
资源限制 选择合适密钥长度 ECC优于RSA

核心优势:

  • 端到端加密保护数据传输安全
  • 身份验证防止中间人攻击
  • 数据完整性确保信息不被篡改
  • 标准化实现跨平台兼容性好

通过合理的配置和优化,HTTPS可以在资源受限的嵌入式环境中高效稳定运行。