首先用sdk的sn工具或者makecert工具生成公鑰和密鑰,推薦makecert,做自己的證書,我做了一個受信任的根證書放在受信任的根證書頒發機構,用這個根證書頒發了一個下級證書放在個認證書裡。把這兩個證書都儲存起來,平時給程式簽名就用這個子證書就行了。以後都用這一個,顯得正規點。

2個都從檔案選擇,這裡用剛才子證書的那個帶密鑰的pfx,需要填入密碼。
這樣編譯後不能防篡改,因為微軟有個跳過機制,這樣隻有生成dll放到gac才會檢查強名稱是否比對,而一個單獨的exe是沒用的,修改裡面一點東西後還是可以執行。微軟說可以在app.config裡加入一條強制檢查,那樣是行了隻要修改exe就沒法執行,但是隻有exe一直帶着那個app.config放在同一目錄才行,如果單獨把exe拿出來就不行了。
怎麼把那句話弄到exe裡呢,我費了半天勁,終于想到了一個辦法,平時隻注意功能實作了,沒想到.net裡的安全機制這麼複雜。
此方法無論是console的還是winform的,無論2.0 3.0 3.5 4.0通用。
如果是console程式,在Main的下面加入
System.Security.Policy.Evidence evi = new System.Security.Policy.Evidence();
evi.AddHost(new System.Security.Policy.Zone(System.Security.SecurityZone.Intranet));
System.Security.PermissionSet ps = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None);
ps.AddPermission(new System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityPermissionFlag.Assertion | System.Security.Permissions.SecurityPermissionFlag.Execution | System.Security.Permissions.SecurityPermissionFlag.BindingRedirects));
ps.AddPermission(new System.Security.Permissions.FileIOPermission(System.Security.Permissions.PermissionState.Unrestricted));
AppDomainSetup ads = new AppDomainSetup();
ads.ApplicationBase = System.IO.Directory.GetCurrentDirectory();
AppDomain app = AppDomain.CreateDomain("JiaoYanShiFouGaiDongGuo", evi, ads, ps, null);
try
{
string JiaoYanShiFouGaiDongGuo = (string)app.CreateInstanceFromAndUnwrap(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName, typeof(string).FullName);
AppDomain.Unload(app);
}
catch (Exception e)
if (e.Message.Contains("8013141A") || e.Message.Contains("8013141a"))
Console.WriteLine("本程式被修改過不允許執行。");
System.Threading.Thread.Sleep(6000);
return;
}
如果是winform程式,在Main的下面加入
System.Security.Policy.Evidence evi = new System.Security.Policy.Evidence();
System.Windows.Forms.MessageBox.Show("本程式被修改過不允許執行。", "危險!", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Stop, System.Windows.Forms.MessageBoxDefaultButton.Button1, System.Windows.Forms.MessageBoxOptions.DefaultDesktopOnly, false);
原理是在桌面程式的zone是mycomputer,是完全信任的,是以就有一個強名稱跳過,這些代碼是建一個Intranet的appdomain,不是完全信任的,是以就會檢查強名稱,這個appdomain是空的,目的不是為了執行裡面的内容而是為了讓.net去檢查強名稱,什麼時候執行到這些代碼什麼時候就會出錯,是以要放到main下面第一句,如果通過檢查不會影響後面的正常代碼。在.net4中上面代碼可以更簡單,有個沙盒GetStandardSandbox,但是2和3中沒有,就不通用了,而這樣無論234都通用,是以4會報某些方法過時,不去管它。
然後編譯就行了,這樣就不用拖家帶口的帶着app.config了,隻要修改一點就不能執行了,會出現“已修改不允許執行”的提示,然後程式會自動關閉。
這樣還不行,反編譯很容易就去掉了,需要混淆。
直接把這個exe混淆,輕按兩下沒法執行吧。别急。
用sn.exe再用剛才那個子證書pfx把這個混淆過的exe再次簽名就可以執行了,好了,這樣exe不但混淆了,而且被加上了強名稱簽名,隻要修改1個位元組就不能運作了。sn -R是重新簽名。
繼續,加上數字簽名,signtool工具,還是用剛才那個子證書,這樣右鍵就可以看到這樣了。
這樣這個程式隻要修改一點,那麼不但不能執行,而且右鍵看數字證書,也通不過,是這樣的
而且exe還是混淆過的,嘿嘿嘿,大功告成。
當然自己用makecert做的證書在自己的機器上,顯示“數字簽名正常”,但是别人的機器上沒有你的證書,會顯示無法驗證此證書之類的,但是還是會校驗,就是說如果把這個exe改了,那麼就會顯示”數字簽名無效“而不是”無法驗證證書“,是以憑這一點也可以驗證是否被篡改過,但是其實用不着了,這個隻是好看用的,因為剛才說了,隻要修改連運作都不能運作了。
如果用的人多了,可以讓使用者把你的證書導入他的證書庫或者去買個真正的證書,那樣就不會出那個紅叉号了。