Hash

我應該使用 HMAC 創建多部分 HASH 令牌嗎

  • December 4, 2021

我有一個帶有自定義 API 身份驗證系統的 Web API,每個使用者都有一個SecretKey和一個公共ApiKey。使用這兩個密鑰客戶端(或使用者)可以為伺服器上的身份驗證生成令牌。

考慮這個函式生成一個身份驗證令牌

public string GetToken(string apiKey, string secretKey, string expireTimestamp)
{
   using var hashAlgorithm = SHA256.Create();
   var byteValue = Encoding.UTF8.GetBytes(apiKey + secretKey + expireTimestamp)
   var byteHash = hashAlgorithm.ComputeHash(byteValue)
   return Convert.ToBase64String(byteHash) + expireTimestamp
}

所以一個令牌是一個組合

$$ token = SHA256(APIKey \mathbin| SecretKey \mathbin| expireTimestamp) \mathbin| expireTimestamp $$

使用這個令牌,我們的 API 有一個獨特的可過期認證系統,

問題:

  1. 我應該連接鍵+ expTime還是應該使用HMAC之類的東西?這種情況是否容易受到沒有 HMAC的長度擴展攻擊等攻擊?
  2. 這個系統的漏洞是什麼(如果有的話)?

使用$$ token = SHA256(APIKey \mathbin| SecretKey \mathbin| expireTimestamp) \mathbin| expireTimestamp $$

不安全,因為它可能導致長度擴展攻擊;

$$ token2 = SHA256(APIKey \mathbin| SecretKey \mathbin| expireTimestamp | \color{red}{extension}) \mathbin| (expireTimestamp | \color{red}{extension}) $$

這是偽造的有效令牌。

NIST 要求 SHA3 候選者能夠抵抗長度擴展攻擊。Keccak 現在將 SHA3 命名為獲勝者,而 Blake2 仍然是競爭中的一個不錯的選擇。兩者都可以抵抗長度擴展攻擊,Keccak 使用容量和 Blake2 使用HAIFA構造,都是安全的長度擴展攻擊。

減輕一個可以使用 HMAC;

$$ token = \operatorname{HMAC-SHA256}(privateKey, publicKey \mathbin| expireTimestamp) \mathbin| expireTimestamp $$請注意,這將呼叫 SHA-256 至少兩次(如果密鑰長於散列函式的塊大小,則為 3 次,SHA-256 為 512 位)。

我們可以使用 BLAKE2 來代替 HMAC。BLAKE2 非常快,甚至我們有一個並行版本BLAKE3並使用

$$ token = \operatorname{BLAKE2}( publicKey \mathbin| privateKey \mathbin|expireTimestamp) \mathbin| expireTimestamp $$是安全的。

NIST 還為 SHA3 標準化了一個 MAC,名為KMAC(或此處)。

BLAKE2 和 KMAC 都優於 HMAC。

如果您堅持使用具有 256 位輸出大小的 SHA2,則使用 SHA-512/256,它是 SHA-512/256 的截斷版本,具有不同的初始值來分隔域。SHA-512/256 不受長度擴展攻擊,並且在設計上對 64 位 CPU 友好。

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