一、問題來由
通常我們通過Visual Studio編寫的winform程序直接編譯之后是一個exe程序,若有引用到第三方dll那么在默認的debug目錄下應該會包含一個exe程序和若干的dll,那么生產環境通常的做法是使用ClickOnce發布程序或者是打包成安裝文件(web安裝部署與winform同理)來部署。
當前要求是要在每次打開程序時讀取注冊表的相關信息,主要用於檢測當前程序是否注冊(客戶要求程序需要通過讀取的機器碼生成注冊碼),若沒有注冊的機器需要添加注冊碼之后並在注冊表內更新,操作注冊表信息在vista以下版本是不會有問題的,但是在windows系統vista及以上版本是需要管理員權限才可以操作注冊表信息的,那么也就是程序必須主動以管理員權限運行,在vista及以上版本有加入UAC(用戶賬戶控制) 的機制,我們可以通過添加新建項->應用程序清單文件(如何主動請求管理員權限)來達到每次運行時主動請求管理員權限以執行我們后續的注冊表操作。
那么問題來了,在我們運行程序時會彈出UAC(用戶賬戶控制)界面詢問是否以管理員權限運行,若以上步驟都有做過的朋友應該對這幅圖不陌生了。
很顯然,最亮是 ....發布者:未知
我剛開始看到此圖的時候想到的是一定是我編譯程序哪漏了一步之類的...於是無盡的度娘和谷歌..最終發現是數字證書問題
二、想要的效果
雖然沒太大的實質性作用(可能我不知道),但是最起碼來說這樣看着要舒服一些....
三、證書究竟是什么
說句實話,我對數字證書也只是知道個大概,這篇文章僅介紹如何讓我們的程序有一個自己的證書文件,數字簽名是什么?(這個解釋很生動也容易理解)
那證書在哪查看呢?最簡單的就是右鍵該程序,有證書簽名過的程序,會有個數字簽名頁,如圖
我們運行一個有證書的程序(右鍵->已管理員身份運行),我們以QQ為例,依次做如下操作查看。
點擊->顯示詳細信息->顯示有關此發布者的證書信息,這個時候就可以看到證書的頒發者和頒發給的信息。
可以看到頒發者的信息是:VeriSign Class 3 Code Signing 2010 CA,這類證書我認為應該是系統內本身就存在的。
可以在控制台查看到該證書的詳細信息。按以下步驟查看:
1:運行內輸入:mmc
2:點擊->文件->添加/刪除管理單元->可用單元內選擇 證書(選擇我的用戶賬戶)->確定,再添加一次證書選擇(計算機用戶)->確定
3:這個時候我們可以在 受信任的根證書頒發機構以及第三方根證書頒發機構 找到上面VeriSign的證書信息。
四、該怎么做呢
通過查閱msdn數字證書相關信息,個人覺得程序的證書要最終發揮作用,應當是將我們自己的證書最終要導入到控制台的受信任的根證書頒發機構,不論可執行程序是在何時注冊的數字證書(可能是已經注冊好放入安裝包,也可能是在安裝時注冊),這時以管理員運行時就會顯示出證書的信息,若沒有在受信任的根證書頒發機構,將顯示發布者未知。
那現在我們要做的也很明確了:
1:首先我們需要生成一個自己的證書
2:我們要將證書導入到 受信任的根證書頒發機構
那如何生成自己的證書呢?微軟提供有Makecert.exe(證書創建工具),也可以使用代碼的方式生成,下面介紹如何使用Makecert.exe創建我們的證書
Makecert.exe這個工具只要我們安裝了visual studio,使用命令提示符就可以了
在命令提示符內輸入
makecert -r -pe -n "CN=你的證書名字" -a sha1 -b 01/01/2012 -e 01/01/2040 -sky exchange -ss my
-ss my:證書生成到個人證書位置,這時我們可以在控制台個人證書位置找到生成的證書了,參數的具體含義查看Makecert.exe
因后續我們需要將證書在安裝時導入到客戶機器上,所以我們將生成好的證書導出,右鍵證書->所有任務->導出,如圖
我們選擇默認的格式導出(.CER)。
現在我們已經有了自己的證書文件,還需要將其導入到 受信任的根證書頒發機構。我們這塊使用代碼實現將其導入,操作類(X509Certificate2)。
X509Certificate2 cert = new X509Certificate2("逗豆豆.cer"); bool my_import = false; bool root_import = false; if (cert != null) { var store2 = new X509Store(StoreName.My, StoreLocation.CurrentUser); store2.Open(OpenFlags.ReadWrite); if (!store2.Certificates.Contains(cert)) { my_import = true; store2.Add(cert); } var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadWrite); if (!store.Certificates.Contains(cert)) { root_import = true; store.Add(cert); } } StringBuilder sb = new StringBuilder(); if (my_import) { sb.Append("成功導入到個人證書目錄\r\n"); } if (root_import) { sb.Append("成功導入到受信任的根證書頒發機構證書目錄\r\n"); } if (sb.Length == 0) MessageBox.Show("已經導入過證書"); else MessageBox.Show(sb.ToString());
上面代碼將證書導入到了個人證書以及受信任的根證書頒發機構,接下來我們需要對我們的可執行程序進行簽名,那簽名與生成證書類似,微軟也有提供一個SignTool.exe(簽名工具),同樣打開命令提示符輸入:signtool sign /a F:\SignatureDemo.exe,參數的具體含義查看SignTool.exe
這個時候右鍵管理員身份運行就可以看到我們要的效果便達到了。但是實際項目中可能需要在安裝程序的時候將證書導入,所以我們可以添加一個安裝類,在重寫安裝的方法內將證書導入:
using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Configuration.Install; using System.Linq; using System.Security.Cryptography.X509Certificates; namespace SignatureDemoInstaller { [RunInstaller(true)] public partial class DemoInstaller : System.Configuration.Install.Installer { public DemoInstaller() { InitializeComponent(); } //-------------重寫安裝方法------------------------------------------------ public override void Install(IDictionary stateSaver) { base.Install(stateSaver); ImportCert(); } //-------------導入證書---------------------------------------------------- private void ImportCert() { X509Certificate2 cert = new X509Certificate2(Context.Parameters["targetdir"] + "\\Bin\\SityTech.cer"); if (cert != null) { var store2 = new X509Store(StoreName.My, StoreLocation.CurrentUser); store2.Open(OpenFlags.ReadWrite); if (!store2.Certificates.Contains(cert)) { store2.Add(cert); } var store = new X509Store(StoreName.Root, StoreLocation.LocalMachine); store.Open(OpenFlags.ReadWrite); if (!store.Certificates.Contains(cert)) { store.Add(cert); } } } } }
五、源代碼什么的
關於如何打包以及部署問題,可以參考文章的最頂端有介紹,這里就不再贅述,實際步驟很簡單,大家完全可以使用代碼生成證書的方式,做到動態生成證書並導入,文章可能看起來排版不這么好,也是給想要深入研究的人一點點小建議,另外使用vs2011之前版本的部署項目,生成的msi文件安裝完畢之后,桌面的快捷方式右鍵指向不到程序目錄並且右鍵也沒有管理員身份運行的選項,需要使用Orca工具編輯一下,安裝完畢Orca之后右鍵Msi程序->用Orca編輯,在左邊的Tables列表中找到Shortcut表,在右邊記錄中找到Directory為DesktopFolder的記錄,修改該記錄的Target屬性為 [TARGETDIR]應用程序名稱.exe即可。
再另外一下..此文章生成證書僅限於學習交流,正式生產環境下,大家應該去證書頒發機構購買,其實很便宜的...,最后demo和msi編輯工具奉上,算是有點用的話,點下推薦吧。