首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++Builder 實作數位簽章:CryptoAPI 簽署與驗證檔案完整性

     編輯:關於C++

數位簽章原理

  1. 發送端:對檔案計算雜湊值 (MD5/SHA1) → 以私鑰加密雜湊值產生簽章 → 傳送檔案 + 簽章。
  2. 接收端:對收到檔案計算雜湊值 → 取得發送者公鑰 → 驗證簽章 (解密簽章比對雜湊值)。
  3. 若檔案被竄改,雜湊值不同,驗證失敗。

CryptoAPI 關鍵函式

函式用途
CryptAcquireContext取得 CSP Handle
CryptCreateHash建立雜湊物件 (CALG_MD5/SHA1)
CryptHashData累加檔案資料計算雜湊
CryptSignHash以私鑰 (AT_SIGNATURE) 加密雜湊值產生簽章
CryptGetUserKey取得公鑰 Handle (AT_SIGNATURE)
CryptVerifySignature驗證簽章

建立檔案簽章 (C++Builder 程式碼)


// 變數宣告
HCRYPTPROV hProv;
HCRYPTHASH hHash;
const int BUF_SIZE = 4096;
BYTE pbBuffer[BUF_SIZE];
BYTE pbSignature[256];
DWORD dwSigLen = 256;
TFileStream* fs = new TFileStream("source.dat", fmOpenRead);

// 1. 連接預設 CSP
if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) Error("CSP 連接失敗");

// 2. 建立 MD5 雜湊
if (!CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash)) Error("建立雜湊失敗");

// 3. 讀取檔案並累加雜湊
DWORD dwRead;
do {
    dwRead = fs->Read(pbBuffer, BUF_SIZE);
    if (!CryptHashData(hHash, pbBuffer, dwRead, 0)) Error("雜湊計算失敗");
} while (dwRead == BUF_SIZE);

// 4. 以私鑰簽署雜湊值
if (!CryptSignHash(hHash, AT_SIGNATURE, NULL, 0, pbSignature, &dwSigLen))
    Error("簽章失敗");

// 5. 將 pbSignature (長度 dwSigLen) 另存為 .sig 檔案
// ...

驗證檔案簽章


// 變數宣告 (同建立簽章)
HCRYPTKEY hPubKey;
// ... 連接 CSP、建立雜湊、讀取檔案計算雜湊 (同上) ...

// 取得公鑰
if (!CryptGetUserKey(hProv, AT_SIGNATURE, &hPubKey)) Error("取得公鑰失敗");

// 讀取 .sig 檔案至 pbSignature, dwSigLen
// ...

// 驗證
if (!CryptVerifySignature(hHash, pbSignature, dwSigLen, hPubKey, NULL, 0)) {
    if (GetLastError() == NTE_BAD_SIGNATURE)
        ShowMessage("檔案已被修改!");
    else
        ShowMessage("驗證過程發生錯誤");
} else {
    ShowMessage("檔案完整,未被竄改。");
}

實務建議

  • 簽章資料可獨立儲存 (.sig 檔) 或附加於檔案尾端 (需自定格式)。
  • 生產環境建議使用 SHA-256 (CALG_SHA_256) 取代 MD5。
  • 私鑰保護:啟用 CSP 使用者保護旗標、考慮硬體安全模組 (HSM)。
  • 錯誤處理:每個 API 檢查回傳值,GetLastError() 取得詳細碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved