一文让你轻松理解WLAN 4-Way Handshake如何生成GTK

关于Wi-Fi的加密认证过程,可以参考如下链接,今天我们来理解如何生成GTK。

WLAN数据加密机制_tls加密wifi-CSDN博客

1 GTK

GTK(Group Temporal Key)是由AP通过GMK生成,长度为128位,并在四次握手的第三步中通过加密的方式发送给STA。具体步骤如下:

  • GTK生成:AP生成一个新的GTK。这个GTK是AP自己生成的随机密钥,用于加密多播和广播通信。
    • Note:所以连接到同一个AP的STA都拥有相同GTK。
  • GTK分发:在四次握手的第三步,AP将GTK加密后发送给STA。加密使用的是PTK中的KEK(Key Encryption Key)部分。

1.1 GTK生成的具体步骤

Wi-Fi使用伪随机函数(PRF)生成GTK。常用的PRF实现基于HMAC-SHA1或HMAC-SHA256,如下图所示:

  • 在WPA和WPA2中,通常使用HMAC-SHA1。
  • 在WPA3中,使用更强的HMAC-SHA256。

Note:

  • 当前GMK由随机数代替;
  • 为了防止GTK泄露,AP应定期生成新的GTK并分发给所有STA。

如上图所示,GTK密钥生成的层级,我们这里重点讲解下生成算法,我们可以看到生成的算法是PRF-Length,其中Length的计算方法如下所示:

  • Length =TK_bits.
    • 其中TK_bits的值参考下图:

1.2 GTK的传递过程

四次握手的具体步骤包括以下内容:

  • 消息1:AP生成ANonce,并发送给STA。
  • 消息2:STA生成SNonce,并发送给AP。STA和AP都计算出PTK。
  • 消息3:
    • AP生成GTK。
    • AP使用PTK中的KEK加密GTK。
    • AP将加密的GTK和一个MIC(Message Integrity Code)发送给STA,以保证消息的完整性和保密性。
  • 消息4:STA接收到加密的GTK后,使用PTK中的KEK解密,得到GTK,并发送确认消息给AP。

1.3 GTK更新和重新分发

AP定期生成新的GTK,并通过以下过程重新分发:

  • 生成新的GTK:使用上述算法和步骤生成新的GTK。
  • 通知STA:通过新的EAPOL-Key消息通知所有连接的STA。
  • 加密传输:使用PTK中的KEK加密新的GTK,并发送给STA。
  • 确认:STA接收到新的GTK后,解密并确认接收。

1.4 hostapd code

static void wpa_group_ensure_init(struct wpa_authenticator *wpa_auth,
                  struct wpa_group *group)
{
    if (group->first_sta_seen)
        return;
    /*
     * System has run bit further than at the time hostapd was started
     * potentially very early during boot up. This provides better chances
     * of collecting more randomness on embedded systems. Re-initialize the
     * GMK and Counter here to improve their strength if there was not
     * enough entropy available immediately after system startup.
     */
    wpa_printf(MSG_DEBUG,
           "WPA: Re-initialize GMK/Counter on first station");
    if (random_pool_ready() != 1) {
        wpa_printf(MSG_INFO,
               "WPA: Not enough entropy in random pool to proceed - reject first 4-way handshake");
        group->reject_4way_hs_for_entropy = true;
    } else {
        group->first_sta_seen = true;
        group->reject_4way_hs_for_entropy = false;
    }

    if (wpa_group_init_gmk_and_counter(wpa_auth, group) < 0 ||
        wpa_gtk_update(wpa_auth, group) < 0 ||
        wpa_group_config_group_keys(wpa_auth, group) < 0) {
        wpa_printf(MSG_INFO, "WPA: GMK/GTK setup failed");
        group->first_sta_seen = false;
        group->reject_4way_hs_for_entropy = true;
    }
}

static int wpa_gtk_update(struct wpa_authenticator *wpa_auth,
              struct wpa_group *group)
{
    struct wpa_auth_config *conf = &wpa_auth->conf;
    int ret = 0;
    size_t len;

    os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
    inc_byte_array(group->Counter, WPA_NONCE_LEN);
    if (wpa_gmk_to_gtk(group->GMK, "Group key expansion",
               wpa_auth->addr, group->GNonce,
               group->GTK[group->GN - 1], group->GTK_len) < 0)
        ret = -1;
    wpa_hexdump_key(MSG_DEBUG, "GTK",
            group->GTK[group->GN - 1], group->GTK_len);

    if (conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
        len = wpa_cipher_key_len(conf->group_mgmt_cipher);
        os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
        inc_byte_array(group->Counter, WPA_NONCE_LEN);
        if (wpa_gmk_to_gtk(group->GMK, "IGTK key expansion",
                   wpa_auth->addr, group->GNonce,
                   group->IGTK[group->GN_igtk - 4], len) < 0)
            ret = -1;
        wpa_hexdump_key(MSG_DEBUG, "IGTK",
                group->IGTK[group->GN_igtk - 4], len);
    }

    if (!wpa_auth->non_tx_beacon_prot &&
        conf->ieee80211w == NO_MGMT_FRAME_PROTECTION)
        return ret;
    if (!conf->beacon_prot)
        return ret;

    if (wpa_auth->conf.tx_bss_auth) {
        group = wpa_auth->conf.tx_bss_auth->group;
        if (group->bigtk_set)
            return ret;
        wpa_printf(MSG_DEBUG, "Set up BIGTK for TX BSS");
    }

    len = wpa_cipher_key_len(conf->group_mgmt_cipher);
    os_memcpy(group->GNonce, group->Counter, WPA_NONCE_LEN);
    inc_byte_array(group->Counter, WPA_NONCE_LEN);
    if (wpa_gmk_to_gtk(group->GMK, "BIGTK key expansion",
               wpa_auth->addr, group->GNonce,
               group->BIGTK[group->GN_bigtk - 6], len) < 0)
        return -1;
    group->bigtk_set = true;
    wpa_hexdump_key(MSG_DEBUG, "BIGTK",
            group->BIGTK[group->GN_bigtk - 6], len);

    return ret;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值