QCryptographicHash
本身不能設置密鑰(Key)。
它是一個用于計算非密鑰型加密哈希的函數,其設計目的和 HMAC 或加密算法完全不同。
下面我詳細解釋為什么,以及如何正確地實現你可能想要的功能。
1. QCryptographicHash
的核心功能:無密鑰哈希
QCryptographicHash
的核心功能是接受輸入數據(如一個字符串或文件內容),然后輸出一個固定長度的、唯一的哈希值(摘要)。相同的輸入永遠產生相同的輸出。
- 輸入:數據 (Data)
- 輸出:哈希值 (Hash/Digest)
- 特點:不需要密鑰。任何人都可以用這個類計算出相同數據的相同哈希值。
它的典型用途是:
- 驗證文件下載是否完整(計算下載文件的 SHA256 并與官方提供的哈希值對比)。
- 生成數據的唯一標識符。
- 用于數字簽名流程的一部分(簽名是使用私鑰對數據的哈希值進行加密,而不是直接加密數據本身)。
2. 如果你需要“帶密鑰的哈希”,你需要的是 HMAC
當你想要驗證一段數據不僅完整,而且來自可信的來源(即擁有密鑰的人)時,就需要用到密鑰。這就是 HMAC 的用途。
- 輸入:數據 (Data) + 密鑰 (Secret Key)
- 輸出:消息認證碼 (MAC)
- 特點:必須要有密鑰。只有擁有相同密鑰的人才能計算出相同的 MAC 值。
它的典型用途是:
- API 請求認證:客戶端使用密鑰對請求參數生成一個簽名(HMAC),服務器用同樣的密鑰驗證簽名,從而確認請求是合法的、未被篡改。
- JSON Web Tokens (JWT):JWT 的簽名部分就是使用 HMAC 生成的。
- 任何需要同時保證完整性和真實性的場景。
3. 如何在 Qt 中實現 HMAC(帶密鑰的哈希)
Qt 提供了專門的類 QMessageAuthenticationCode
來計算 HMAC。你應該使用這個類,而不是 QCryptographicHash
。
示例:使用 QMessageAuthenticationCode
計算 HMAC-SHA256
#include <QMessageAuthenticationCode>
#include <QDebug>int main() {// 你的原始消息QByteArray message = "Important data: user=123, action=delete";// 你的密鑰(必須保密!)QByteArray secretKey = "MySuperSecretKey123!";// 選擇哈希算法(這里以 SHA256 為例)QCryptographicHash::Algorithm hashAlgorithm = QCryptographicHash::Sha256;// 計算 HMACQMessageAuthenticationCode hmacCalculator(hashAlgorithm);hmacCalculator.setKey(secretKey); // 設置密鑰hmacCalculator.addData(message); // 添加數據QByteArray result = hmacCalculator.result(); // 計算最終結果QByteArray hmacHex = result.toHex(); // 轉換為十六進制字符串,便于傳輸和存儲qDebug() << "Message:" << message;qDebug() << "HMAC (hex):" << hmacHex;// 輸出類似: "HMAC (hex): a1b2c3d4e5f6..."// --- 驗證端 --- //// 當接收方收到消息和這個HMAC后,可以用同樣的密鑰和算法重新計算一次HMAC。// 如果計算出的HMAC與發送來的完全一致,則證明消息是完整且真實的。return 0;
}
4. 一個常見的混淆:加密 (Encryption) vs. 哈希 (Hashing)
你可能還會想問:“那我可以用它來加密密碼嗎?” 答案是:不能,而且這是兩個截然不同的概念。
-
哈希 (Hashing with
QCryptographicHash
)- 單向的:無法從哈希值還原出原始數據。
- 目的:驗證完整性、生成指紋。
- 例如:SHA256, MD5。
-
加密 (Encryption)
- 雙向的:使用密鑰將明文變為密文,也可以使用密鑰(或配對密鑰)將密文還原為明文。
- 目的:保密性,防止信息被未授權者讀取。
- 例如:AES, RSA。
對于密碼存儲,正確的做法是使用密碼學哈希函數,但必須是專門為密碼設計的(如 bcrypt, PBKDF2),而不是 QCryptographicHash
這種通用哈希。Qt 中可以使用 QPasswordDigestor
(詳見我上一個回答)。
總結
| 你的需求 | 應該使用的 Qt 類 | 說明 |
| :— | :— | :— |
| 計算數據的哈希值(校驗文件完整性) | QCryptographicHash
| 無密鑰,通用哈希計算。 |
| 計算帶密鑰的哈希(API簽名,消息認證) | QMessageAuthenticationCode
(HMAC) | 需要密鑰,用于驗證真實性和完整性。 |
| 加密/解密數據(保證數據機密性) | 需要使用加密庫(如 Qt 的 QSslSocket
相關功能或第三方庫) | 需要密鑰,雙向過程。 |
| 安全地存儲用戶密碼 | QPasswordDigestor
(Qt >= 5.12) | 使用慢哈希算法(如 PBKDF2),內含鹽值和迭代次數。 |
結論:
QCryptographicHash
沒有設置密鑰的功能。 如果你需要用到密鑰,你的真實需求很可能是:
- 消息認證 -> 使用
QMessageAuthenticationCode
(HMAC)。 - 加密數據 -> 使用加密庫(如 AES)。
- 哈希密碼 -> 使用
QPasswordDigestor
。