2013年7月30日 星期二

利用自然人憑證對檔案簽章

簽章的目的在防止檔案被篡改及確認檔案的發行者。
行政院國家資通安全會報技術服務中心為防止網頁漏洞,將逐步推動網頁應用程式不使用ActiveX計畫,而初步則先要求ActiveX取得數位簽章,以確保來源安全。
為了證明程式的來源,一般公司行號可以利用經濟部的工商憑證,或者向獨立的憑證公司購買憑證來對程式(或檔案)進行簽章,如果個人則可以利用自然人憑證來對自己開發的程式進行簽章。底下將介紹如何使用自然人憑證對自己開發的程式進行數位簽章。
一、預備動作:
(一)首先要安裝一台可以讀取自然人憑證的讀卡機(及驅動程式)
(二)到內政部憑證管理中心下載 HiCOS卡片管理工具:如下圖所示,在「文件下載」頁籤內之「檔案下載」項目中。
(三)安裝HiCOS卡片管理工具,安裝完成後,可以在開始功能表中看到「HiCOS PKI Smart Card」
註:1.如果沒有正確安裝卡片管理工具,則底下執行簽章時,將無法讀取自然人憑證內的憑證資料。
       2.上面的預備動作只需做一次就好,不用每次進行簽章都重新來遍!
二、利用 VS2008 的SignTool 來進行簽章
本篇並不是 SignTool 的教學,所以不會詳細介紹 SignTool的指令及用法,只選用最簡單的精靈模式來對 .dll 檔做簽章示範!
(一)由 VS2008 啟動 Visual Studio 2008 命令提示字元
(因我的環境是 Win7 64Bit ,所以我選用 Visual Studio 2008 x64 Win64 命令提示字元,請您依自身的環境啟用適當的提示字元)

(二)在命令提示字元內執行  「signtool signwizard」以啟動簽章精靈

(三)出現簽章精靈歡迎畫面後,請按「下一步」

(四)利用「瀏覽」找到要進行簽章的檔案,一次只能選用一個檔案
一般我們會對 *.exe, *.dll, *.ocx 做個簽章,或都對 *.cab 的包裝檔進行簽章
選定要簽章的檔案後,請按「下一步」

(五)簽署選項只要使用預設的「一般」即可

(六)出現簽署憑證畫面時,請按「從存放區選取
如果沒有成功安裝「HiCOS卡片管理工具」,會發現存放區中沒有自然人憑證資料可供選用。在自然人憑證選項中會出現兩組憑證,隨便選一項,但利用「檢視憑證」查看是否合適(見(七)),如果不合適再重選就好了!
因為我之前有做過簽章,所以存放區會有選用資訊(上圖),但並不表示已經內含憑證資料,所以如果自然人憑證沒有插到讀卡機時,會出現下圖的提示畫面,如果在執行(六)的步驟之前卡片已放入讀卡機,就不會出現這個提示畫面!
 

(七)當選用一組簽章憑證後,可利用「檢視憑證」鈕,查看憑證內容,要用來簽章檔案的憑證必須符合「確保軟體來自軟體發行者」這個使用目的。
當確認選用的憑證無誤後,就再按「下一步
註:自然人憑證內有二組 公-私 金鑰對,一組是用來加解密用,一組是用來簽章及驗證簽章用,必須選對使用目的

(八)資料描述的目的是要提供使用者詳細的資訊,以判斷是不是要接受這個檔案,這是一組選用的項目,不填也沒關係
如果是簽署ActiveX而供 IE 安裝使用時,在安裝之前會顯示相關內容供使用者閱覽!

(九)加上時間戳記,是指定網路上的時間伺服器提供日期時間資訊,對這次的簽章加入時間戳記,如果有加入時間戳記,緃使同一個簽章檔,在不同時間對同一個檔案進行簽章,其簽章壓碼也會不一樣!
不過這項不勾選也沒關係,如果有勾選,就要指定一個時間伺服器的網址。

(十)最後會出現相關資訊供您再確認,如果確認無誤,就大膽地按下「完成」吧!

(十一)按下「完成」後,Signtool 會去讀自然人憑證卡片上的資料,這時就會要求您輸入憑證的密碼!
這組密碼是自然人憑證的密碼,而不是要您去設定一組密碼哦! 不要隨便輸入!

(十二)正確輸入自然人憑證密碼,並按下「OK」,稍等一下下,就會跳出「數位簽章精靈執行成功」的畫面,恭喜! 您已經完成一個檔案的簽章了!

三、檢視已簽章的檔案之簽章內容
利用檔案總管在檔案上按滑鼠右鍵,然後選「內容」
接著切換到「數位簽章」的頁籤(要有經過數位簽章的檔案才會有此頁籤)
點一下簽章清單中的一組簽章,然後按「詳細資料」,再從數位簽章詳細資料視窗中選擇「檢視憑證」即可看到簽章的資訊!

附註:如果簽章是檔案時,在二之(六)簽署憑證時,就可以選擇憑證檔案,可是自然人憑證為了安全考量,金鑰是在卡片內部產生,而且依內政部宣稱,私鑰是不能從卡片匯出的! 所以要用自然人憑證簽章,一定要有讀卡機,每次簽章時,都必須讀取卡片上的憑證資訊!

2013年7月29日 星期一

保護 Cookie 的安全(Secure 與 HttpOnly),在ASP.NET環境

Cookie 的 Secure 屬性是強迫 Cookie 在傳輸時使用 SSL 加密機制。
Cookie 的 HttpOnly 屬性是指示 Cookie 只供瀏覽器與WebServer之間之網頁溝通使用,不允許JavaScript 存取Cookie (document.cookie)。

一、於程式中產生的Cookie,可以利用 HttpOnly 及 Secure 屬性,針對特定的 Cookie 要求
myCookie.HttpOnly = true

myCookie.Secure = true;

二、透過 WebConfig 設定,讓所有的 Cookie 都啟用 Secure:
 ASP.Net 2.0 以後,可以在 WebConfig的 <system.web>區段內加入:
<system.web>
   <httpCookies httpOnlyCookies="true" requireSSL="true" />
   ....
</system.web>

但上面的設定方式,在ASP.Net 1.x 並不支援,所以必須在 Global.asax 中動手腳:
在Global.asax.vb 中加入下面這一段程式 ,強制每一個Cookie 都加入指定的屬性

   Sub Application_EndRequest(ByVal sender As Object, ByVal e As EventArgs)
        ' 於每一個要求開始時引發
        For Each sCookie As String In Response.Cookies
            Response.Cookies(sCookie).Secure = True
            Response.Cookies(sCookie).HttpOnly = True
        Next
    End Sub

三、 Secure HttpOnly 是兩個屬性,請視需要設定(即沒有必須同時都設)

四、雖然完成上面的設定,可以讓應用程式在傳送 Cookies 時加入 Secrure 及 HttpOnly=true 的旗標,但 ASPX 的 SessionCookie (.ASPXAUTH) 卻仍無法以 SSL 傳送,弱點掃描時會發生「Cookie Security: Cookie Not Sent Over SSL」的風險,解決方式是在 中加入 requireSSL="true",如下所示:
<authentication mode="Forms">
  <forms loginUrl="http://mojsingle.moj/mojsingle/script/mojlogin1.asp" timeout="30" protection="All" requireSSL="true" />
</authentication>

-------------------------------------------------------------------------------------------------
緣由:
早期的 ASP.NET 程式最近被黑箱掃描程式找到一項「中風險」項目:
[加密的階段作業 (SSL) Cookie 中遺漏安全屬性]

測試類型:
 應用程式層次測試
威脅分類:
 應用程式隱私測試
原因:
 Web 應用程式會透過 SSL 傳送未受保護的 Cookie
安全風險:
 有可能竊取在加密階段作業期間傳送的使用者和階段作業資訊 (Cookie)
CWE:614
技術說明:
 在應用程式測試期間,偵測到在加密階段作業中,所測試的 Web 應用程式設定了不含 "secure" 屬性的 Cookie。
 由於這個 Cookie 未包含 "secure" 屬性,因此,也可能在未加密的階段作業期間將它傳給網站。

由於此 Cookie 並非我程式中產生的,而是系統為 Session 所建立,為解決此一中風險弱點,只好採用 Global.asax.vb 中加入控制程式的方法因應!

2013年7月15日 星期一

ADODB 的 Command.parameters 的吊詭!

程式存取資料庫建議使用 Prepare 方式來傳遞參數,所以一般會將查詢敘述寫成:
dim sql as string = "Insert myTable(fName1 ,fName2 ,fName3) values(?, ?, ?)"
三個 ? 對應到三個要傳遞進來的參數,所以會用下列方法來準備參數

Dim cmd As New ADODB.Command
cmd.CommandText = sql
With cmd
       .Parameters.Append(cmd.CreateParameter("fName1", ADODB.DataTypeEnum.adVarChar, , 50))
       .Parameters.Append(cmd.CreateParameter("fName2", ADODB.DataTypeEnum.adVarChar, , 50))
       .Parameters.Append(cmd.CreateParameter("fName3", ADODB.DataTypeEnum.adVarChar, , 50))
       .Parameters("fName1").value= "value1"
       .Parameters("fName2").value= "value2"
       .Parameters("fName3").value= "value3"
End With
cmd.Execute()

上面的程式看起來似乎沒有什麼問題,可是執行時卻會出現,因為參數的個數不相符。

可是將
dim sql as string = "Insert myTable(fName1 ,fName2 ,fName3) values(?, ?, ?)"
換成
dim sql as string = "Insert myTable(fName1 ,fName2 ,fName3) values(@fName1, @fName2, @fName3)"
就沒有問題了!

從上面的實驗得知,當參數位置使用「?」時,系統會自動為它建立一組 parameter,
可是用「@fname1」方式時卻不會!

故如果用「?」來準備參數,必要時需利用 .parameters.delete(index) 方法先將系統預留的參數區清除!

2013年7月13日 星期六

將VB6 轉換(升級)成 VB.NET

  因專案需要將VB6 開發的應用程式轉換到 .NET,原本打算重新撰寫,可是改寫一樣需遵照原來的作業邏輯,單單重新設計表單及選擇替代的元件所花的時間可能就不短,最後嘗試就利用 VS2008 的專案轉換功能,將VB6轉案直接升級到 .Net 2.0。

專案轉換後,雖然程式碼中有些必須升級或改寫的地方,但 forms 的設計都沒有問題,可是把專換後的專案複製到家裡的環境時,卻有部分 Forms 出現下列錯誤:

類別未登錄 (發生例外狀況於 HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))


  奇怪!奇怪! 原本以為是漏COM檔案,可是一再比對,檔案並沒有少啊! 上網找,都說是因為 VS的編譯設定的問題,只要將編譯目標改成 x86 就可以(詳參考:http://www.dotblogs.com.tw/hung-chin/archive/2011/07/30/32306.aspx),可是照改之後,問題依舊。

  仔細看錯誤的地方,VS 報錯是在這一行;
 Me._SSTab2_TabPage0.Controls.Add(Me._mctPic_0)

  有問題的是 _mctPic_0 這個變數沒有定義,找到定義這一行:
 Me._mctPic_0 = New AxMSChart20Lib.AxMSChart

應該是 AxMSChart20Lib.AxMSChart 這個元件的問題,上網查的結果,AxMSChart20Lib.AxMSChart 是在  mschrt20.ocx 裡。

  所以,只要將  mschrt20.ocx 複製到 System32 (如果是 64bit 的Win7 就複製到 SysWOW64 裡),然後以系統管理員身分開啟 cmd ,並切換到 System32 (64 bit是切換到 SysWOW64),然後執行
regsvr32 mschrt20.ocx

問題解決了!

所以,縱使相同的錯誤息訊,也可能是不同的起因!