Aes

使用 AES-ctr 和 hmac-sha2 的安全嵌入式/微控制器加密

  • March 3, 2017

嵌入式設備是一個低功耗的 8 位微控制器(記憶體使用限制為大約 10kb 程式碼,1kb ram)。由於該設備由電池供電並且手動服務應該是最少的,因此更強大的處理器不是一個選項。

吞吐量非常有限,因此性能不是太大的問題。

我們提出的系統是帶有 hmac-sha 身份驗證的 AES-ctr 模式加密:

// encryption_key, mac_key, device_id are all independent, secure random,
// unique per device pre-programmed values

// aes-ctr encryption (pseudocode)
first_nonce = nonce = device_id || counter++
for block in plaintext
   ciphertext.append(aes_ctr_encrypt_block(encryption_key, block, nonce))
   nonce = device_id || counter++ // counter is saved in non-volatile storage (e.g. flash or eeprom) to avoid re-using after power down

// authenticate nonce + ciphertext (pseudocode)
data = first_nonce || ciphertext
mac_tag = hmac_sha2(data, mac_key)

// send or store mac_tag, nonce and ciphertext
send(mag_tag || data)

然後接收方應使用 deviceID 查找 mac_tag 並驗證它是否匹配。通過檢查計數器是否大於先前收到的計數器,我們希望消除重放攻擊。

如果驗證通過,則數據被解密。

這是一個安全的系統嗎?另外,將 hmac_sha2 的輸出截斷為 128 位會有什麼影響?

Fgrieu 已經發布了一個很好的答案,我不會嘗試重複。但是,這裡有一些額外的觀察:

  • 對於嵌入式系統,您可能需要考慮使用CMAC -AES 而不是 HMAC,因為您可以重用 AES 實現,並且不需要單獨的雜湊函式。
  • 進一步考慮使用 SIV 模式 ( RFC 5297 )。它與 CTR+CMAC 非常相似,但提供了額外的保護以防止意外的 nonce 重用,並且還不需要單獨的密碼和 MAC 密鑰。
  • 請注意 nonce 重用,特別是如果您不使用 SIV。(但如果可能,請使用 SIV!)在每條消息之後保存 nonce 到 flash 通常不是一個好主意,所以通常的方法是在每個 1024 消息塊之前寫入 nonce + 1024 到 flash。重新啟動時,只需從 flash 中的最後一個 nonce 值恢復,它應該大於實際使用的最後一個 nonce。(此外,確保即使寫入過程中斷電也不會造成任何損壞;有處理此問題的標準技術,但它們並不是真正特定於加密的。)
  • 考慮在您的消息中包含時間戳和/或序列號,以防止重放攻擊。如果您可能在兩個方向或多個渠道上使用相同的密鑰,也可以使用發送者和接收者 ID 標記您的消息。(這些可能是明文形式,但它們確實需要包含在 MAC 中。對於 SIV,您可以將它們包含為“關聯數據”。)

我對系統的理解如下:

  • 數據塊使用 AES-CTR 加密,使用 key encryption_key,通過連接device_id生成 IV 並counter保存在 Flash 或 EEPROM 中,每次使用時遞增;
  • 加密data的 256 位mac_tag使用 HMAC-SHA256 和mac_key.

這在理論上是合理的,如果

  1. device_id是獨特的。
  2. encryption_key並且mac_key保持秘密,並且最好是設備唯一的(例如,工廠通過一些健全的密鑰派生功能device_id和不洩漏的主密鑰進行多樣化;當然,只有在設備和持有主密鑰的主密鑰之間進行通信時才有效;對於設備到設備的通信,我們回到全域共享密鑰或公鑰密碼學)。
  3. counter不重疊或以其他方式返回到較早的狀態。

截斷mac_tag為 128 位是可以的,除非監管要求另有規定。

但是請注意,在一個不是為該目標而設計的嵌入式系統中,很難對任何事情保密。有 JTAG 埠、探測、緩衝區溢出、其他側通道、誘發故障..

然後是實現錯誤,包括但不限於:在接收端解密某些東西,即使它沒有通過完整性檢查;未能在接收方檢查計數器是否增加;只有在counter傳輸開始後才在傳輸端有效地遞增(包括因為一些 RAM 記憶體);否則會錯過上面的目標 3,因為快閃記憶體或 EEPROM 更新期間的電源損耗很難可靠地處理,尤其是面對在更糟糕的時刻切斷電源的對手(包括舊墨菲由於快閃記憶體電荷泵引起電源故障而導致復位),以及根據電源電壓、溫度、老化或薛定諤貓的健康狀況,中斷的擦除或程式會導致無法可靠讀取相同值的位。

引用自:https://crypto.stackexchange.com/questions/20506