在Access 2000 數(shù)據(jù)庫中,為了安全起見,可以為所建的數(shù)據(jù)庫設置密碼。但是,密碼忘了怎么辦?別急,這里介紹一種密碼*方法。
用磁盤編輯工具打開Access 2000 所建的數(shù)據(jù)庫,在庫文件的地址00000042處開始的40個字節(jié)是Access 2000庫的密碼位。如果一個未加密的庫,這40個字節(jié)原始數(shù)據(jù)依次為:29 77 EC 37 F2 C8 9C FA 69 D2 28 E6 BC 3A 8A 60 FB 18 7B 36 5A FE DF B1 D8 78 13 43 60 23 B1 33 9B ED 79 5B 3D 39 7C 2A 。當你給數(shù)據(jù)庫設置了密碼后,這40個字節(jié)就變成了密鑰。因此,要*密碼而不需保持原庫的密碼,只要將00000042 處開始的40個字節(jié)還原成原始數(shù)據(jù)就行了。要做到這一點,你可用磁盤編輯工具或將以下所附的程序稍加修改,把以上所列40個數(shù)據(jù)填到00000042開始處。
但是,有沒有辦法既能*密碼又能保持原密碼呢?有。要做到這一點,必須搞清楚Access 2000庫的加密原理。事實上,Access 2000庫的加密原理很簡單。當你設置了密碼后,Access 2000 就將你的密碼(請注意你所輸入的密碼是ASCII字符)的ASCII碼與以上的40個字節(jié)數(shù)據(jù)進行異或操作,因此,從庫文件的地址00000042開始的40個字節(jié)就變成了密鑰了。例如,如果你設置的密碼為12345678901234567890(注意:最多只能設20個ASCII字符),經(jīng)過異或操作后,則從00000042處開始的40個字節(jié)的數(shù)據(jù)就變成了 18 77 DE 37 C1 C8 A8 FA 5C D2 1E E6 8B 3A B2 60 C2 18 4B 36 6B FE ED B1 EB 78 27 43 55 23 87 33 AC ED 41 5B 04 39 4C 2A 。大家都知道,一個數(shù)據(jù)經(jīng)過一次異或操作后,再一次經(jīng)過同樣的異或操作就可還原了。因此,對已經(jīng)設置了密碼的Access 2000庫,只要將40個密鑰數(shù)據(jù)與原始的40個數(shù)據(jù)進行一次異或操作就可得到密碼了。
順便提一下,由于ACCESS 2000對每個密碼字符采用雙字節(jié)表示,故40個字節(jié)原始數(shù)據(jù)可依次分為20組,每組代表一個密碼字符,進行異或操作的是每組的第一個字節(jié),第二個字節(jié)不變。
//根據(jù)網(wǎng)上經(jīng)驗和方法用C#做一個*程序
// 本程序最多取16位密碼
using System.IO;
using System.Windows.Forms;
class Access
{
// 獲取密碼
static string GetPassword(string file)
{ // 未加密的文件0x42開始至0x61之前的每間隔一字節(jié)的數(shù)值
byte[] baseByte = { 0xbe,0xec,0x65,0x9c,0xfe,0x28,0x2b,0x8a,0x6c,0x7b,0xcd,0xdf,0x4f,0x13,0xf7,0xb1, };
byte flagByte = 0x0c; // 標志 0x62 處的數(shù)值
string password = \"\";
try
{
FileStream fs = File.OpenRead(file);
fs.Seek(0x14, SeekOrigin.Begin);
byte ver = (byte)fs.ReadByte(); // 取得版本, 1為Access2000, 0為Access97
fs.Seek(0x42, SeekOrigin.Begin);
byte[] bs = new byte[33];
if (fs.Read(bs, 0, 33) != 33) return \"\";
byte flag = (byte)(bs[32] ^ flagByte);
for(int i = 0; i < 16; i++)
{
byte b = (byte)(baseByte^bs[i*2]);
if (i%2==0 && ver==1) b ^= flag; //Access 2000
if (b > 0) password += (char)b;
}
}
catch {}
return password;
}
// 主入口
static void Main()
{
OpenFileDialog f = new OpenFileDialog();
if (f.ShowDialog() != DialogResult.OK) return;
MessageBox.Show(\"密碼:[\" + GetPassword(f.FileName) + \"]\", \"密碼\");
}
}
用磁盤編輯工具打開Access 2000 所建的數(shù)據(jù)庫,在庫文件的地址00000042處開始的40個字節(jié)是Access 2000庫的密碼位。如果一個未加密的庫,這40個字節(jié)原始數(shù)據(jù)依次為:29 77 EC 37 F2 C8 9C FA 69 D2 28 E6 BC 3A 8A 60 FB 18 7B 36 5A FE DF B1 D8 78 13 43 60 23 B1 33 9B ED 79 5B 3D 39 7C 2A 。當你給數(shù)據(jù)庫設置了密碼后,這40個字節(jié)就變成了密鑰。因此,要*密碼而不需保持原庫的密碼,只要將00000042 處開始的40個字節(jié)還原成原始數(shù)據(jù)就行了。要做到這一點,你可用磁盤編輯工具或將以下所附的程序稍加修改,把以上所列40個數(shù)據(jù)填到00000042開始處。
但是,有沒有辦法既能*密碼又能保持原密碼呢?有。要做到這一點,必須搞清楚Access 2000庫的加密原理。事實上,Access 2000庫的加密原理很簡單。當你設置了密碼后,Access 2000 就將你的密碼(請注意你所輸入的密碼是ASCII字符)的ASCII碼與以上的40個字節(jié)數(shù)據(jù)進行異或操作,因此,從庫文件的地址00000042開始的40個字節(jié)就變成了密鑰了。例如,如果你設置的密碼為12345678901234567890(注意:最多只能設20個ASCII字符),經(jīng)過異或操作后,則從00000042處開始的40個字節(jié)的數(shù)據(jù)就變成了 18 77 DE 37 C1 C8 A8 FA 5C D2 1E E6 8B 3A B2 60 C2 18 4B 36 6B FE ED B1 EB 78 27 43 55 23 87 33 AC ED 41 5B 04 39 4C 2A 。大家都知道,一個數(shù)據(jù)經(jīng)過一次異或操作后,再一次經(jīng)過同樣的異或操作就可還原了。因此,對已經(jīng)設置了密碼的Access 2000庫,只要將40個密鑰數(shù)據(jù)與原始的40個數(shù)據(jù)進行一次異或操作就可得到密碼了。
順便提一下,由于ACCESS 2000對每個密碼字符采用雙字節(jié)表示,故40個字節(jié)原始數(shù)據(jù)可依次分為20組,每組代表一個密碼字符,進行異或操作的是每組的第一個字節(jié),第二個字節(jié)不變。
//根據(jù)網(wǎng)上經(jīng)驗和方法用C#做一個*程序
// 本程序最多取16位密碼
using System.IO;
using System.Windows.Forms;
class Access
{
// 獲取密碼
static string GetPassword(string file)
{ // 未加密的文件0x42開始至0x61之前的每間隔一字節(jié)的數(shù)值
byte[] baseByte = { 0xbe,0xec,0x65,0x9c,0xfe,0x28,0x2b,0x8a,0x6c,0x7b,0xcd,0xdf,0x4f,0x13,0xf7,0xb1, };
byte flagByte = 0x0c; // 標志 0x62 處的數(shù)值
string password = \"\";
try
{
FileStream fs = File.OpenRead(file);
fs.Seek(0x14, SeekOrigin.Begin);
byte ver = (byte)fs.ReadByte(); // 取得版本, 1為Access2000, 0為Access97
fs.Seek(0x42, SeekOrigin.Begin);
byte[] bs = new byte[33];
if (fs.Read(bs, 0, 33) != 33) return \"\";
byte flag = (byte)(bs[32] ^ flagByte);
for(int i = 0; i < 16; i++)
{
byte b = (byte)(baseByte^bs[i*2]);
if (i%2==0 && ver==1) b ^= flag; //Access 2000
if (b > 0) password += (char)b;
}
}
catch {}
return password;
}
// 主入口
static void Main()
{
OpenFileDialog f = new OpenFileDialog();
if (f.ShowDialog() != DialogResult.OK) return;
MessageBox.Show(\"密碼:[\" + GetPassword(f.FileName) + \"]\", \"密碼\");
}
}