W55MH32 的 TLS 硬件加密功能说明

WIZnet W55MH32 的 TLS 硬件加密功能说明

目录

WIZnet W55MH32 的 TLS 硬件加密功能说明

1. 简介

2. 什么是 TLS?

3. TLS 握手和密钥交换

4. 演示部分

5. 运行结果

6. 结论

1. 简介

W55MH32是一款由WIZnet设计的增强型32位微控制器,其特性非常适合安全的网络应用 。它拥有216MHz的处理器核心,以及高达1024KB的Flash内存和96KB的SRAM 。至关重要的是,它包含了用于关键加密操作的专用硬件,例如内置了DES、AES和SHA算法的 硬件加密算法单元,以及一个真随机数发生器(TRNG) 。这些硬件特性对于实现高性能和安全的TLS 1.2至关重要,因为它们能将计算密集型任务从主CPU上卸载 。W55MH32还支持硬连线TCP/IP协议栈和10/100M以太网MAC和PHY,使其成为一个强大的安全互联网通信平台 。

2. 什么是 TLS?

传输层安全(TLS)是一种加密协议,旨在通过计算机网络提供安全的通信。它确保三个关键的安全属性:

  • 机密性(Confidentiality): 它对数据进行加密,以防止窃听和未经授权的访问。

  • 完整性(Integrity): 它使用消息认证码(MAC)来确保数据在传输过程中没有被篡改。

  • 真实性(Authenticity): 它使用数字证书和签名来验证服务器(以及可选的客户端)的身份。

TLS 是从SSL(安全套接层)演变而来的,是用于保护网络流量(HTTPS)和其他数据通信的当前标准。它是现代互联网安全的一个基本组成部分。

3. TLS 握手和密钥交换

W55MH32 上的 TLS 1.2 握手利用芯片的硬件有效地建立安全会话。

Client Hello (客户端问候)

客户端发送一个"Client Hello"消息,其中包括:

  1. 支持的TLS版本 。

  2. 支持的密码套件和压缩方法列表 。

  3. 一个32字节的客户端随机数 。这个随机数是使用W55MH32的TRNG功能生成的,该功能有四个独立的真随机源,可以一次性生成128位的随机数 。这确保了随机数的质量对于加密目的来说是最高的 。

Server Hello (服务器问候)

服务器发送一个"Server Hello"消息,其中包括:

  1. 选择的TLS版本 。

  2. 选择的密码套件(例如,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384)和压缩方法 。

  3. 一个32字节的服务器随机数 。

  4. 服务器的数字证书,如果选择DHE密钥交换,还包括服务器的临时DH公钥 。

认证与密钥交换(客户端执行)

客户端接收服务器的消息并对服务器的身份进行认证 。

  1. 客户端的MCU使用硬件加密算法单元中的W55MH32的SHA硬件来验证服务器证书上的数字签名,这确认了证书的真实性和完整性 。

  2. 客户端随后使用服务器的临时DH公钥和自己的私钥独立计算一个预主密钥 。

Client Key Exchange (客户端密钥交换)

客户端向服务器发送其密钥交换消息:

  • DHE:客户端的临时公钥

    1. 客户端使用自己的TRNG功能生成其临时DH公钥并发送给服务器 。

    2. 服务器随后使用这个公钥以及自己的私钥来计算相同的预主密钥 。

  • RSA:预主密钥

    1. 客户端生成一个秘密,并使用服务器的公钥安全地将其发送给服务器 。

    2. 客户端使用W55MH32的TRNG功能生成一个48字节的预主密钥 。

    3. 客户端使用证书中的服务器公钥对该预主密钥进行加密 。

    4. 客户端将加密后的预主密钥发送给服务器 。

    5. 只有拥有匹配私钥的服务器才能解密它 。

ChangeCipherSpec 和 Finished

这是握手的最后验证阶段 。

  1. 客户端和服务器根据预主密钥和随机数派生出主密钥和会话密钥 。

  2. 双方发送一个ChangeCipherSpec消息,表示接下来的所有通信都将加密 。

  3. 客户端发送一个Finished消息 。此消息使用新的会话密钥进行加密,并包含所有先前握手消息的哈希值 。

  4. W55MH32的SHA硬件用于计算这个哈希值 。服务器解密它并验证哈希值,以确认密钥交换成功且握手未被篡改 。

数据通信

加密数据传输:

一旦握手完成,所有应用数据都使用会话密钥进行保护 。

  1. 应用数据使用硬件加密算法单元中的W55MH32的AES硬件模块进行加密 。

  2. 使用W55MH32的SHA硬件和会话MAC密钥计算消息认证码(MAC) 。

  3. 加密后的数据和MAC被发送给另一方 。

  4. 接收方使用W55MH32的AES硬件解密数据,并使用W55MH32的SHA硬件验证MAC 。

  5. 验证成功保证了数据的完整性和真实性 。

4. 演示部分

W55MH32的TLS 1.2功能演示将遵循以下步骤:

  1. 硬件与网络设置:初始化W55MH32的10/100M以太网MAC和PHY以建立物理连接 。配置硬连线TCP/IP协议栈进行网络通信 。

    网络配置初始化,其包含的 MAC 地址、IP 地址、网关、子网掩码、DNS 服务器地址和 DHCP 模式等网络配置参数。

/* network information */
wiz_NetInfo default_net_info = {
    .mac  = {0x00, 0x08, 0xdc, 0x12, 0x22, 0x12},
    .ip   = {10, 0, 1, 140}, 
    .gw   = {10, 0, 1, 254},
    .sn   = {255, 255, 255, 0},
    .dns  = {8, 8, 8, 8},
    .dhcp = NETINFO_DHCP
};

定义三个变量ethernet_buf作为网络数据收发缓冲区,ssl_target_ip指定了百度服务器的目标IP地址,tlsContext则用于维护TLS连接的所有状态和配置信息。

uint8_t ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {0};
uint8_t ssl_target_ip[4] = {182, 61, 244, 181}; // baidu
wiz_tls_context tlsContext;

硬件与网络设置,初始化硬件、加密模块、TRNG、定时器,初始化wiztoe并检查PHY链接,最后初始化网络。


  /* hardware initialization */
    rcc_clk_config();
    delay_init();
    console_usart_init(115200);

	printf("W55MH32 TLS Example\r\n");

    /* hardware crypt initialization */
    *(uint32_t *)(0x400210F0) = 0x01;
    *(uint32_t *)(0x40016C00) = 0xCDED3526;
    *(uint32_t *)(0x40016CCC) = 0x07;

    /* hardware TRNG enable */
    TRNG_Out(ENABLE);

    tim3_init();

    /* wiztoe init */
    wiz_toe_init();
	getSHAR(default_net_info.mac);
    wiz_phy_link_check();

    network_init(ethernet_buf, &default_net_info);
  1. TLS安全连接建立流程

接下来开始执行加密通信的初始化和连接建立过程:首先获取并打印加密库版本信息,然后创建SSL套接字并初始化TLS上下文,接着通过TCP连接到目标服务器的443端口,最后完成TLS握手协议建立安全连接,并打印消息表示MbedTLS传输测试即将开始。

uint32_t ver = wiz_crypt_version();
    printf("WIZnet CARD Secure Test Demo V1.0, secure lib version is V%02x.%02x.%02x.%02x\n", ver >> 24, (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);
    printf("WIZnet CARD Crypt Test V1.0 start......\r\n");

	/* open socket */
    wiz_tls_socket(&tlsContext, SOCKET_SSL_ID, LOCAL_PORT);

	/* tls init */
    wiz_tls_init(&tlsContext, 2000, (char *)ssl_target_ip, NULL, NULL, NULL);
    
	/* connect server*/
	connect(tlsContext.socket_fd, (uint8_t *)ssl_target_ip, SSL_TARGET_PORT);
    
	/* tls handshake */
	wiz_tls_connect(&tlsContext, (char *)ssl_target_ip, SSL_TARGET_PORT);

    printf("W55MH32 MbedTLS Transmission test start......\r\n");
  1. TLS初始化与握手过程

wiz_tls_init 函数用于初始化TLS客户端连接,参数包括:TLS上下文结构体指针、接收超时时间(毫秒)、目标服务器域名/IP地址、根证书字符串(验证服务器身份)、客户端证书字符串和私钥字符串(用于客户端认证)。

 int wiz_tls_init(wiz_tls_context *tlsContext, uint32_t recv_timeout, char *domain_name, char *root_ca, char *client_cert, char *pkey)
{
    int         ret             = 1;
    const char *pers            = "ssl_client1";
    const char *alpnProtocols[] = {"x-amzn-mqtt-ca", NULL};
#if defined(MBEDTLS_ERROR_C)
    char error_buf[100];
#endif

#if defined(MBEDTLS_DEBUG_C)
    mbedtls_debug_set_threshold(MBEDTLS_DEBUG_LEVEL);
#endif

    /*
    Initialize session data
  */
#if defined(MBEDTLS_ENTROPY_C)
    tlsContext->entropy = malloc(sizeof(mbedtls_entropy_context));
#endif
    tlsContext->ctr_drbg = malloc(sizeof(mbedtls_ctr_drbg_context));
    tlsContext->ssl      = malloc(sizeof(mbedtls_ssl_context));
    tlsContext->conf     = malloc(sizeof(mbedtls_ssl_config));
    tlsContext->cacert   = malloc(sizeof(mbedtls_x509_crt));
    tlsContext->clicert  = malloc(sizeof(mbedtls_x509_crt));
    tlsContext->pkey     = malloc(sizeof(mbedtls_pk_context));

#if defined(MBEDTLS_ENTROPY_C)
    mbedtls_entropy_init(tlsContext->entropy);
#endif

    mbedtls_ctr_drbg_init(tlsContext->ctr_drbg);
    mbedtls_ssl_init(tlsContext->ssl);
    mbedtls_ssl_config_init(tlsContext->conf);
    mbedtls_x509_crt_init(tlsContext->cacert);
    mbedtls_x509_crt_init(tlsContext->clicert);
    mbedtls_pk_init(tlsContext->pkey);

    const int *ciphersuite_list = mbedtls_ssl_list_ciphersuites();
    while (*ciphersuite_list != 0)
    {
        const char *name = mbedtls_ssl_get_ciphersuite_name(*ciphersuite_list);
        if (name != NULL)
            printf("%s\r\n", name);
        ciphersuite_list++;
    }
    /*
    Initialize certificates
  */
#if defined(MBEDTLS_ENTROPY_C)
    if ((ret = mbedtls_ctr_drbg_seed(tlsContext->ctr_drbg, mbedtls_entropy_func, tlsContext->entropy,
                                     (const unsigned char *)pers, strlen(pers)))
        != 0)
    {
        printf(" failed\r\n  ! mbedtls_ctr_drbg_seed returned -0x%x\r\n", -ret);
        return -1;
    }
#endif

#if defined(MBEDTLS_DEBUG_C)
    mbedtls_ssl_conf_dbg(tlsContext->conf, WIZnetDebugCB, stdout);
#endif

    /*
    Parse certificate
  */
    if (root_ca != NULL)
    {
        uint16_t root_ca_len = strlen(root_ca);
        printf(" Loading the CA root certificate len = %d\r\n", root_ca_len);
        ret = mbedtls_x509_crt_parse(tlsContext->cacert, (const unsigned char *)root_ca, root_ca_len + 1);
        if (ret < 0)
        {
            printf(" failed\r\n  !  mbedtls_x509_crt_parse returned -0x%x while parsing root cert\r\n", -ret);
            return -1;
        }
        printf("ok! mbedtls_x509_crt_parse returned -0x%x while parsing root cert\r\n", -ret);

        uint8_t ip_temp[4];
        if (!is_ipaddr((uint8_t *)domain_name, (uint8_t *)ip_temp))
        {
            if ((ret = mbedtls_ssl_set_hostname(tlsContext->ssl, domain_name)) != 0)
            {
                printf(" failed mbedtls_ssl_set_hostname returned %d\r\n", ret);
                return -1;
            }
        }
        else
        {
            if ((ret = mbedtls_ssl_set_hostname(tlsContext->ssl, NULL)) != 0)
            {
                printf(" failed mbedtls_ssl_set_hostname returned %d\r\n", ret);
                return -1;
            }
        }
        printf("ok! mbedtls_ssl_set_hostname returned %d\r\n", ret);
        tlsContext->root_ca_option = MBEDTLS_SSL_VERIFY_REQUIRED;
    }
    else
    {
        tlsContext->root_ca_option = MBEDTLS_SSL_VERIFY_NONE;
    }

    if (client_cert != NULL && pkey != NULL)
    {
        uint32_t client_cert_len = strlen(client_cert);
        uint32_t pkey_len        = strlen(pkey);

        ret = mbedtls_x509_crt_parse((tlsContext->clicert), (const unsigned char *)client_cert, client_cert_len + 1);
        if (ret != 0)
        {
            printf(" failed\r\n  !  mbedtls_x509_crt_parse returned -0x%x while parsing device cert\r\n", -ret);
            return -1;
        }
        printf("ok! mbedtls_x509_crt_parse returned -0x%x while parsing device cert\r\n", -ret);

        ret = mbedtls_pk_parse_key(tlsContext->pkey, (const unsigned char *)pkey, pkey_len + 1, NULL, 0, mbedtls_ctr_drbg_random, tlsContext->ctr_drbg);
        if (ret != 0)
        {
            printf(" failed\r\n  !  mbedtls_pk_parse_key returned -0x%x while parsing private key\r\n", -ret);
            return -1;
        }
        printf("ok! mbedtls_pk_parse_key returned -0x%x while parsing private key\r\n", -ret);
    }

    if ((ret = mbedtls_ssl_config_defaults(tlsContext->conf,
                                           MBEDTLS_SSL_IS_CLIENT,
                                           MBEDTLS_SSL_TRANSPORT_STREAM,
                                           MBEDTLS_SSL_PRESET_DEFAULT))
        != 0)
    {
        printf(" failed mbedtls_ssl_config_defaults returned %d\r\n", ret);
        return -1;
    }

    printf("socket_fd = %d\r\n", tlsContext->socket_fd);
    mbedtls_ssl_conf_authmode(tlsContext->conf, tlsContext->root_ca_option);
    mbedtls_ssl_conf_ca_chain(tlsContext->conf, tlsContext->cacert, NULL);
    mbedtls_ssl_conf_rng(tlsContext->conf, SSLRandomCB, tlsContext->ctr_drbg);

    if (client_cert != NULL && pkey != NULL)
    {
        if ((ret = mbedtls_ssl_conf_own_cert(tlsContext->conf, tlsContext->clicert, tlsContext->pkey)) != 0)
        {
            printf("failed! mbedtls_ssl_conf_own_cert returned %d\r\n", ret);
            return -1;
        }
        printf("ok! mbedtls_ssl_conf_own_cert returned %d\r\n", ret);
    }

    mbedtls_ssl_conf_endpoint(tlsContext->conf, MBEDTLS_SSL_IS_CLIENT);
    if (recv_timeout == 0)
        recv_timeout = 2000;
    mbedtls_ssl_conf_read_timeout(tlsContext->conf, recv_timeout);

    if ((ret = mbedtls_ssl_setup(tlsContext->ssl, tlsContext->conf)) != 0)
    {
        printf(" failed mbedtls_ssl_setup returned -0x%x\r\n", -ret);
        return -1;
    }
    mbedtls_ssl_set_bio(tlsContext->ssl, (void *)tlsContext->socket_fd, SSLSendCB, SSLRecvCB, SSLRecvTimeOutCB);

    printf("return 1\r\n");
    return 1;
}

在该测试过程中(设置了2秒超时和目标服务器IP,但未配置证书验证参数)。

	/* tls init */
    wiz_tls_init(&tlsContext, 2000, (char *)ssl_target_ip, NULL, NULL, NULL);

TLS握手过程:启动与服务器的TLS连接。调用W55MH32基于硬件的TRNG来生成随机数,并使用SHA引擎执行验证 。

TRNG_Out函数通过开启或关闭TRNG(真随机数生成器)模块,为TLS握手过程提供必要的真随机数来源,保障TLS协议中密钥生成等安全操作所需的随机熵源。

/**
  * @brief  TRNG_Stop
  * @param  
  * @retval None
  */
void TRNG_Out(FunctionalState NewState)
{
	if (NewState != DISABLE)
	{
		RCC->RCC_SYSCFG_CONFIG = 0x01;
		SYSCFG->SYSCFG_LOCK = 0xCDED3526;
		SYSCFG->SSC_CLK_EN |= TRNG_RNG_ENABLE;
	}
	else
	{
		RCC->RCC_SYSCFG_CONFIG = 0x00;
		SYSCFG->SSC_CLK_EN &= ~TRNG_RNG_ENABLE;
	}
}
/**************************      (C) COPYRIGHT  2024  WIZnet    *****END OF FILE****/

wiz_tls_connect是 TLS 客户端核心函数,作用是执行 TLS 握手:通过循环调用mbedtls_ssl_handshake处理握手流程,启用证书验证时会校验服务器证书合法性(该测试为证书无校验模式),握手成功后输出协商的加密套件,最终完成 TLS 安全连接建立或返回错误。

int wiz_tls_connect(wiz_tls_context *tlsContext, char *addr, unsigned int port)
{
    int      ret;
    uint32_t start_ms = millis(), flags;

    printf(" Performing the SSL/TLS handshake...\r\n");
    while ((ret = mbedtls_ssl_handshake(tlsContext->ssl)) != 0)
    {
        if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
        {
            //mbedtls_strerror(ret, (char *) tempBuf, DEBUG_BUFFER_SIZE );
            //printf( " failed\n\r  ! mbedtls_ssl_handshake returned %d: %s\n\r", ret, tempBuf );
            printf(" failed\n\r  ! mbedtls_ssl_handshake returned -0x%x\n\r", -ret);
            return (-1);
        }
        delay_ms(10);
    }

    if (tlsContext->root_ca_option == MBEDTLS_SSL_VERIFY_REQUIRED)
    {
        printf("  . Verifying peer X.509 certificate...\r\n");

        /* In real life, we probably want to bail out when ret != 0 */
        if ((flags = mbedtls_ssl_get_verify_result(tlsContext->ssl)) != 0)
        {
            char vrfy_buf[512];
            printf("failed\r\n");
            mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), "  ! ", flags);
            printf("%s\r\n", vrfy_buf);
            return -1;
        }
        else
        {
            printf("ok\r\n");
        }
    }
    printf(" ok\n\r    [ Ciphersuite is %s ]\n\r",
           mbedtls_ssl_get_ciphersuite(tlsContext->ssl));
    return (0);
}

mbedtls_ssl_handshake函数是mbedTLS库中执行SSL/TLS握手协议的核心实现,通过循环调用握手步骤函数完成加密参数协商、密钥交换和身份验证等过程,直到握手完成或出现错误,最终建立起客户端与服务器之间的安全加密通信通道。

/*
 * Perform the SSL handshake
 */
int mbedtls_ssl_handshake(mbedtls_ssl_context *ssl)
{
    int ret = 0;

    /* Sanity checks */

    if (ssl == NULL || ssl->conf == NULL) {
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }

#if defined(MBEDTLS_SSL_PROTO_DTLS)
    if (ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM &&
        (ssl->f_set_timer == NULL || ssl->f_get_timer == NULL)) {
        MBEDTLS_SSL_DEBUG_MSG(1, ("You must use "
                                  "mbedtls_ssl_set_timer_cb() for DTLS"));
        return MBEDTLS_ERR_SSL_BAD_INPUT_DATA;
    }
#endif /* MBEDTLS_SSL_PROTO_DTLS */

    MBEDTLS_SSL_DEBUG_MSG(2, ("=> handshake"));

    /* Main handshake loop */
    while (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) {
        ret = mbedtls_ssl_handshake_step(ssl);

        if (ret != 0) {
            break;
        }
    }

    MBEDTLS_SSL_DEBUG_MSG(2, ("<= handshake"));

    return ret;
}

#if defined(MBEDTLS_SSL_RENEGOTIATION)
#if defined(MBEDTLS_SSL_SRV_C)
  1. 安全通信:握手完成后,应用程序可以发送和接收数据,利用W55MH32的AES和SHA硬件来处理所有加密、解密和完整性检查,从而使主CPU能够专注于应用逻辑 。

    TLS 握手成功后,所有数据通过加密通道收发,核心是调用wiz_tls_write(加密发送)和wiz_tls_read(加密接收)。

    unsigned int wiz_tls_read(wiz_tls_context *tlsContext, unsigned char *readbuf, unsigned int len)
{
    return mbedtls_ssl_read(tlsContext->ssl, readbuf, len);
}

unsigned int wiz_tls_write(wiz_tls_context *tlsContext, unsigned char *writebuf, unsigned int len)
{
    return mbedtls_ssl_write(tlsContext->ssl, writebuf, len);
}

通过已建立的TLS安全连接向百度服务器发送HTTP GET请求获取网页内容,并在无限循环中持续接收和打印服务器返回的响应数据,实现了一个简单的HTTPS客户端功能来获取并显示百度首页的HTML内容。

   
    if (1)
    {
        printf("W55MH32 get baidu.com html content......\r\n");
        mbedtls_ssl_conf_read_timeout(tlsContext.conf, 200);
        sprintf(ethernet_buf, "GET / HTTP/1.1\r\nHost: www.baidu.com\r\nUser-Agent: W55MH32/1.0\r\nAccept: text/html\r\nConnection: close\r\n\r\n");
        wiz_tls_write(&tlsContext, (unsigned char *)ethernet_buf, strlen(ethernet_buf));

        while (1)
        {
            recv_len = wiz_tls_read(&tlsContext, ethernet_buf, ETHERNET_BUF_MAX_SIZE - 1);

            if (recv_len > 0)
            {
                printf("recv_len:%d\r\n", recv_len);
                ethernet_buf[recv_len] = '\0';
                printf("Received: %s", ethernet_buf);
            }
        }
    }

5. 运行结果

我们通过例程测试使用 HTTPS 获取百度网页信息,通过串口打印显示W55MH32 PHY链路正常、DHCP获网成功,加载加密库后完成TLS握手(套件TLS-RSA-WITH-AES-128-GCM-SHA256),发送请求并接收百度响应。

W55MH32 启动 MbedTLS 传输测试并尝试获取百度 HTML 内容,成功接收 490 字节数据,内容为百度返回的响应信息。

通过Wireshark进行抓包展示了从 TCP 三次握手建立连接,接着开展 TLS 握手(涵盖客户端 hello、服务器 hello、密钥交换等操作)以构建安全通信通道并传输应用数据。

我们知道,HTTPS协议是基于TCP/IP协议的,所以在TLS握手前客户端与百度服务器分别进行了TCP三次握手。

接着可以看到TLS握手建立安全通道的过程,在Wireshark的显示过滤器中输入表达式ip.addr == 192.168.1.13 and tls过滤出TLS协议数据包, W55MH32为客户端(192.168.1.13)访问百度服务器(182.61.244.181)。

第一次握手报文(164):W55MH32->百度 发送TLS消息「Client Hello」;

第二次握手报文(166、176):

  • 百度->W55MH32 发送TLS消息「Server Hello」;

  • 百度->W55MH32 发送TLS消息「Certificate」,「Server Hello Done」;

第三次握手报文(192、193、194):W55MH32->百度 发送TLS消息「Client Key Exchange」,「Change Cipher Spec」,「Encrypted Handshake Message」;

第四次握手报文(200):百度->W55MH32 发送TLS消息「Change Cipher Spec」,「Encrypted Handshake Message」。 其握手过程如图所示:

TLS第一次握手:client -> server (Client Hello) 客户端向服务端发送:

  • 客户端支持的协议;

  • 已经使用的TLS版本;

  • 随机数Random;

  • 支持的密码套件。

接下来我们看几个TLS协议中的重要字段(Version、Random、SessionID和Cipher Suites)。

从上图中可以看到当前通信安全层协议版本(Version)为TLS 1.2。其实TLS共总有4个版本,最新为TLS 1.3,具体如下:

  • TLS 1.3:发布于2018年,TLS 1.3是TLS协议的最新版本,大幅简化了握手过程,提高了性能和安全性。它删除了一些不安全的加密算法,并引入了0-RTT(零往返时间)握手,以减少延迟。

  • TLS 1.2:TLS 1.2发布于2008年,它引入了更强的加密算法和更灵活的密码套件选择,修复了许多安全漏洞,是目前广泛使用的版本。(当前样例中百度网站使用的就是TLS 1.2协议)

  • TLS 1.1:TLS 1.1发布于2006年,引入了一些改进,包括对CBC(Cipher Block Chaining)模式的安全性改进,但仍然存在一些已知的安全问题。

  • TLS 1.0:TLS 1.0于1999年发布,是SSL 3.0的升级版本,修复了一些安全漏洞,但仍然存在一些安全问题。

Random用于密钥的制作,这里我们将第一次握手中客户端发送给服务端的随机数记为Client Random,记住这个随机数,后面还会用到。

SessionID用来表示客户端是否想复用先前存在的session。如果不复用,则此字段为0;如果想要复用,则此字段为想要复用的sessionID。是否复用由服务端确定。

Cipher Suites密码套件列表会全部发给服务端,服务端从中挑选一个最安全的密码套件返回客户端。

密码套件的格式通常由一系列的加密算法和相关参数组成。一般来说,它的格式包含以下几个部分:

  • 密钥交换算法:用于协商会话密钥,例如 Diffie-Hellman(DHE)、ECDHE等。

  • 身份验证算法:也称签名算法用于验证对端身份,例如RSA。

  • 加密算法:用于实际数据传输的加解密,例如 AES(Advanced Encryption Standard)、RC4 等。

  • 数据摘要算法:用于计算哈希,主要是用于验证数据的完整性,防止信息被篡改。

格式:「密钥交换算法 + 签名算法(认证算法) + 对称加密算法 + 摘要算法」。其中密钥交换算法和签名算法可以相同,此时就会合二为一。

不同的密码套件组合提供了不同的安全性和性能特点,服务器和客户端在进行 TLS 握手时会协商选择双方都支持的 Cipher Suite 来建立安全连接。

客户端发送完「Client Hello」,服务端向客户端发送的ACK确认消息,代表上面的「Client Hello」已经收到。这里也可以看出服务端是通过普通的TCP 的ACK消息去应答「Client Hello」。

TLS第二次握手:server -> client (1.Server Hello; 2.Certificate,Server key Exchange,Server Hello Done) 这一次握手时,server向client连续发送了两个报文:

  • Server Hello:服务端为了证明自己的身份,会发送「Server Certificate」给客户端,这个消息里含有数字证书;

  • Certificate,Server Hello Done:目的是告诉客户端,我已经把该给你的东西都给你了,本次打招呼完毕。

服务端发送报文(Server Hello)服务端向客户端发送:

  • 服务端支持的协议;

  • 使用的TLS版本;

  • 随机数Random;

  • 服务端选用的密码套件。

上图中可以看到,服务端也生成了一个随机数,并发送给了客户端,服务端生成的随机数记为Server Random。

客户端和服务端就已确认了 TLS 版本和使用的密码套件TLS_RSA_WITH_AES_128_GCM_SHA256。

服务端发送报文:Certificate,Server Hello Done。

TLS第三次握手client -> server (Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message)

客户端向服务器传递加密预主密钥,更改密码规范,和加密握手的消息。

TLS 第四次握手server -> client (Change Cipher Spec,Encrypted Handshake Message)

服务器也是同样的操作,发送「Change Cipher Spec」和「Encrypted Handshake Message」消息,如果双方都验证加密和解密没问题,那么TLS握手正式完成。

TLS握手完成后,客户端与服务端的所有通信内容均被加密,如果没有会话密钥则无法解密通信内容。

服务器遵循 TLS 协议规范发出关闭警报(close_notify),随即发送 TCP RST 报文以快速释放连接资源。 

6. 结论

在像嵌入式微控制器这样的受限设备上实现TLS 1.2是一项具有挑战性但又必不可少的安全连接任务 。通过利用TRNG、SHA256和AES256等硬件加速功能,开发人员可以创建健壮且高性能的安全通信通道 。W55MH32为这些功能提供了专用硬件,包括其硬件加密算法单元TRNG,使得主CPU能够专注于应用逻辑,这对于高性能和安全的嵌入式系统至关重要 。

本 PPT 介绍了制药厂房中供配电系统的总体概念与设计要点,内容包括: 洁净厂房的特点及其对供配电系统的特殊要求; 供配电设计的一般原则与依据的国家/行业标准; 从上级电网到工厂变电所、终端配电的总体结构与模块化设计思路; 供配电范围:动力配电、照明、通讯、接地、防雷与消防等; 动力配电中电压等级、接地系统形式(如 TN-S)、负荷等级与可靠性、UPS 配置等; 照明的电源方式、光源选择、安装方式、应急与备用照明要求; 通讯系统、监控系统在生产管理与消防中的作用; 接地与等电位连接、防雷等级与防雷措施; 消防设施及其专用供电(消防泵、排烟风机、消防控制室、应急照明等); 常见高压柜、动力柜、照明箱等配电设备案例及部分设计图纸示意; 公司已完成的典型项目案例。 1. 工程背景与总体框架 所属领域:制药厂房工程的公用工程系统,其中本 PPT 聚焦于供配电系统。 放在整个公用工程中的位置:与给排水、纯化水/注射用水、气体与热力、暖通空调、自动化控制等系统并列。 2. Part 01 供配电概述 2.1 洁净厂房的特点 空间密闭,结构复杂、走向曲折; 单相设备、仪器种类多,工艺设备昂贵、精密; 装修材料与工艺材料种类多,对尘埃、静电等更敏感。 这些特点决定了:供配电系统要安全可靠、减少积尘、便于清洁和维护。 2.2 供配电总则 供配电设计应满足: 可靠、经济、适用; 保障人身与财产安全; 便于安装与维护; 采用技术先进的设备与方案。 2.3 设计依据与规范 引用了大量俄语标准(ГОСТ、СНиП、SanPiN 等)以及国家、行业和地方规范,作为设计的法规基础文件,包括: 电气设备、接线、接地、电气安全; 建筑物电气装置、照明标准; 卫生与安全相关规范等。 3. Part 02 供配电总览 从电源系统整体结构进行总览: 上级:地方电网; 工厂变电所(10kV 配电装置、变压
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值