Access MDB 檔案密碼保護機制在 Access 97 到 2000/2002 版本間發生重大變化。本文揭示其加密演算法細節,並提供 C++Builder 參考實作,旨在協助開發者理解資料庫安全弱點以加強防護。
0x42 起始,連續 13 位元組{0x86,0xFB,0xEC,0x37,0x5D,0x44,0x9C,0xFA,0xC6,0x5E,0x28,0xE6,0x13}password[i] = file[0x42+i] ^ key[i]經 UltraEdit 二進位比對發現:
0x62)// 參考空密碼檔案基準值(需隨機器/時間動態取得)
char PassSource2k[13] = {0xA1,0xEC,0x7A,0x9C,0xE1,0x28,0x34,0x8A,0x73,0x7B,0xD2,0xDF,0x50};
// 對應加密標誌位:0x13
// 解密流程
BYTE encFlag = file[0x62] ^ emptyFile[0x62]; // 取得動態加密標誌
for (int i = 0; i < 13; ++i) {
BYTE encByte = file[0x42 + i*2]; // 交錯讀取
BYTE baseByte = emptyFile[0x42 + i*2];
BYTE half = encByte ^ baseByte; // 第一階段
if (i % 2 == 0) // 隔一個位元組
password[i] = half ^ encFlag; // 第二階段:與標誌位 XOR
else
password[i] = half; // 奇數索引僅第一階段
if (password[i] < 0x20 || password[i] > 0x7E) break; // 遇非可列印字元結束
}
void __fastcall TMainForm::GetMdbPass() {
char PassStrTemp[26], Ver, EncrypFlag;
int FileHandle = FileOpen(MdbFileName, fmOpenRead);
if (FileHandle < 0) { ShowMessage("檔案開啟錯誤!"); return; }
// 讀取版本標誌 (0x14: 0=Access97, 1=Access2000/2002)
FileSeek(FileHandle, 0x14, 0);
FileRead(FileHandle, &Ver, 1);
// 讀取加密標誌 (0x62)
FileSeek(FileHandle, 0x62, 0);
FileRead(FileHandle, &EncrypFlag, 1);
// 讀取加密密碼區塊 (0x42, 26 bytes)
FileSeek(FileHandle, 0x42, 0);
FileRead(FileHandle, &PassStrTemp, 26);
FileClose(FileHandle);
AnsiString MdbPassword, MdbVersion;
if (Ver < 1) { // Access 97
MdbVersion = "Access 97";
if ((PassStrTemp[0] ^ PassSource97[0]) == 0)
MdbPassword = "密碼為空!";
else {
for (int i = 0; i < 13; ++i)
MdbPassword += char(PassStrTemp[i] ^ PassSource97[i]);
}
} else { // Access 2000/2002
MdbVersion = "Access 2000 or 2002";
for (int i = 0; i < 13; ++i) {
char t1;
if (i % 2 == 0)
t1 = char(0x13 ^ EncrypFlag ^ PassStrTemp[i*2] ^ PassSource2k[i]);
else
t1 = char(PassStrTemp[i*2] ^ PassSource2k[i]);
MdbPassword += t1;
}
}
// 簡易驗證:首字元是否可列印
if (MdbPassword[1] < 0x20 || MdbPassword[1] > 0x7E)
MdbPassword = "密碼為空!";
EditMdbPassword->Text = MdbPassword;
EditMdbVersion->Text = MdbVersion;
}
| 弱點 | 影響 | 緩解措施 |
|---|---|---|
| 靜態/半靜態金鑰 | 離線破解極易 | 改用 Access 2007+ ACCDB 格式(AES-256 加密) |
| 密碼長度限制 13 字元 | 暴力破解空間小 | 啟用資料庫層級加密而非僅用戶級密碼 |
| 無鹽值/雜湊 | 彩虹表攻擊有效 | 應用層自行雜湊存儲,不依賴 Jet 引擎密碼 |
| 檔案層級權控缺失 | 複製檔案即可離線攻擊 | 部署於受管伺服器,配合 NTFS/EFS 加密 |
結論:MDB 密碼機制本質上是混淆而非加密。生產環境務必遷移至 ACCDB (ACE 引擎) 或 SQL Server Express / SQLite (SQLCipher) 等現代儲存方案,並在應用層實施強雜湊與存取控制。