一個(gè)公司做100個(gè)網(wǎng)站百度一鍵安裝
關(guān)于Wi-Fi的加密認(rèn)證過(guò)程,可以參考如下鏈接,今天我們來(lái)理解如何生成GTK。
WLAN數(shù)據(jù)加密機(jī)制_tls加密wifi-CSDN博客
1 GTK
GTK(Group Temporal Key)是由AP通過(guò)GMK生成,長(zhǎng)度為128位,并在四次握手的第三步中通過(guò)加密的方式發(fā)送給STA。具體步驟如下:
- GTK生成:AP生成一個(gè)新的GTK。這個(gè)GTK是AP自己生成的隨機(jī)密鑰,用于加密多播和廣播通信。
- Note:所以連接到同一個(gè)AP的STA都擁有相同GTK。
- GTK分發(fā):在四次握手的第三步,AP將GTK加密后發(fā)送給STA。加密使用的是PTK中的KEK(Key Encryption Key)部分。
- Note:關(guān)于KEK請(qǐng)參考鏈接:WLAN 4-Way Handshake如何生成PTK?-CSDN博客
1.1 GTK生成的具體步驟
Wi-Fi使用偽隨機(jī)函數(shù)(PRF)生成GTK。常用的PRF實(shí)現(xiàn)基于HMAC-SHA1或HMAC-SHA256,如下圖所示:
- 在WPA和WPA2中,通常使用HMAC-SHA1。
- 在WPA3中,使用更強(qiáng)的HMAC-SHA256。
Note:
- 當(dāng)前GMK由隨機(jī)數(shù)代替;
- 為了防止GTK泄露,AP應(yīng)定期生成新的GTK并分發(fā)給所有STA。
如上圖所示,GTK密鑰生成的層級(jí),我們這里重點(diǎn)講解下生成算法,我們可以看到生成的算法是PRF-Length,其中Length的計(jì)算方法如下所示:
- Length =TK_bits.
- 其中TK_bits的值參考下圖:
1.2 GTK的傳遞過(guò)程
四次握手的具體步驟包括以下內(nèi)容:
- 消息1:AP生成ANonce,并發(fā)送給STA。
- 消息2:STA生成SNonce,并發(fā)送給AP。STA和AP都計(jì)算出PTK。
- 消息3:
- AP生成GTK。
- AP使用PTK中的KEK加密GTK。
- AP將加密的GTK和一個(gè)MIC(Message Integrity Code)發(fā)送給STA,以保證消息的完整性和保密性。
- 消息4:STA接收到加密的GTK后,使用PTK中的KEK解密,得到GTK,并發(fā)送確認(rèn)消息給AP。
1.3 GTK更新和重新分發(fā)
AP定期生成新的GTK,并通過(guò)以下過(guò)程重新分發(fā):
- 生成新的GTK:使用上述算法和步驟生成新的GTK。
- 通知STA:通過(guò)新的EAPOL-Key消息通知所有連接的STA。
- 加密傳輸:使用PTK中的KEK加密新的GTK,并發(fā)送給STA。
- 確認(rèn):STA接收到新的GTK后,解密并確認(rèn)接收。
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;
}