DEV Community

Michael
Michael

Posted on • Updated on

HTTP3之key update

背景

Key update属于传输协议(QUIC)的特点之一,必须在handshake完成以后进行。
TLS1.3的key update使用专门的握手消息通知对方,我这边要修改密钥了,下次我们使用新的密钥沟通,起到密钥同步效果。
QUIC-TLS中则使用short header packet中的Key Phase bit是否翻转(toggled)来通知key update。1-RTT包中默认为0,不兼容TLS1.3的key update message。
另外,QUIC-TLS要求双方同时更新keys,而TLS1.3双方是独立的处理。

实现

实现使用ngtcp2库

  1. 首先一方endpoing使用接口初始化key udpate, 告诉库应用程序想要更新keys,告知对方要key update
    if ((res = ngtcp2_conn_initiate_key_update(c->conn, timestamp())) != 0)
    {
        print_debug(ERROR, "ngtcp2_conn_initiate_key_update: %s(The previous key update has not been confirmed yet; or key update is too frequent; or new keys are not available yet.)", ngtcp2_strerror(res));
        return -1;
    }
Enter fullscreen mode Exit fullscreen mode
  1. 使用ngtcp2的key update callback,他用于库告诉应用程序你需要key update了
const ngtcp2_crypto_ctx *crypto_ctx = ngtcp2_conn_get_crypto_ctx(c->conn);
const ngtcp2_crypto_aead *aead = &(crypto_ctx->aead);
int keylen = ngtcp2_crypto_aead_keylen(aead);
int ivlen = ngtcp2_crypto_packet_protection_ivlen(aead);

uint8_t rx_key[64], tx_key[64];
if (ngtcp2_crypto_update_key(c->conn, rx_secret, tx_secret,rx_aead_ctx,rx_key, rx_iv, tx_aead_ctx, tx_key, tx_iv, current_rx_secret, current_tx_secret, secretlen) != 0)
{
    print_debug(ERROR, "ngtcp2_crypto_update_key failed");
    return -1;
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)