第12講:將安全隱患扼殺在搖籃之中——用Microsoft .NET來保護資料和應用程式的安全

來源:互聯網
上載者:User

2005.3.22 歐岩亮

課程介紹

如何應用.NET Framework中的特性來保護代碼的安全

 

基礎內容

熟悉.NET開發

 

課程安排

身分識別驗證

授權

加密

強命名程式集

代碼訪問安全

中介層安全

如何避免SQL注入

 

身分識別驗證

使用Credential來唯一標明一個使用者

可以使用Microsoft Windows的整合身分識別驗證,使用使用者登入Windows時的使用者憑證

編寫自己的使用者身分識別驗證的程式,應用程式來系統管理使用者憑證

System.Security.IIdentity介面和System.Security.GenericIdentity類

System.Security.Principal.WindowsIdentity.GetCurrent().Name

 

示範一

Authentication

這裡的密碼是1234的MD5加密密文,NorthwindCredentials的建構函式傳入了使用者名稱以及使用者的三個角色。另一個使用者fred只有銷售許可權。

下面是NorthwindCredentials類

建構函式

Identity就是一個使用者的標識,roles是使用者的角色數組。

登入表單

如果是登入驗證成功,那麼將當前執行線程的CurrentPrincipal使用者憑證,置成了WebService返回的creds對象。

 

Authorization

使用基於角色的安全

可以通過編程實現基於角色的授權

角色可以代表商業流程中的工作職責,例如:秘書、經理、管理員、總監等

用角色的方式來系統管理使用者會更加簡便

 

如何使用基於角色的安全

PrincipalPermissionAttribute和SecurityAction.Demand

在類或者方法上加上PrincipalPermission就表示要訪問類或者方法需要通過身分識別驗證。Authenticated為true表示必須要通過身分識別驗證,Role表示使用者需要訪問所必須具有的角色。.NET在啟動並執行時候就會去查看當前運行線程的CurrentPrincipal,判斷使用者是不是有相應的許可權。

IPrincipal.isInRole()

判斷當前的使用者是不是有某一個角色。Context.User是Asp.net裡面來訪問當前使用應用程式使用者的Class。這個例子通過判斷目前使用者所具有的角色來賦予介面元素不同的屬性。

 

示範二

Authorization

SecurityAction.Demand表示需要具有某種東西,Role表示需要具有Manager的角色許可權。這裡Manager是個字串常量,

如果不具有相應許可權想訪問這個類,就會拋出異常。

這樣做還是會有一些弊端,如果我們想通過資料庫來規定使用者需要哪些角色能訪問,就不能通過這種標籤的方式。這種標籤加許可權限制訪問的方式只能夠用硬代碼規定角色的常量字串名稱。

所以.NET為我們提供了另外一種方式。

在建構函式中,我們可以執行個體化一個PrincipalPermission,將角色通過字串方式傳入,而不同在類上面加標籤。如果frmProducts類不使用,那麼就不會得到此類的任何方法;如果要使用,必須通過建構函式中的許可權驗證。

為了更好的使用者體驗,我們把介面元素的屬性也根據許可權來設定可見與不可見。

 

加密

加密將位元組打亂

對稱式加密與非對稱式加密

對稱式加密適用一個相同的密鑰進行加密/解密

非對稱式加密使用一個金鑰組進行加密/解密,加密與解密的密鑰是不同的(公開金鑰/私密金鑰對)

非對稱式加密演算法更加安全

對稱式加密演算法更加高效

System.Security.Cryptography名稱空間

如何進行密鑰管理

 

示範三

加密

加密位元組序列,我們使用了.NET內建的一種加密方法,DESCryptoServiceProvider。 

解密方法

CryptoStream實際上是對MemoryStream的封裝,當我們對cs進行寫操作的時候,會把解密後的資料寫入MemoryStream。

這裡加密後的資料要進行一個Base64的轉換,因為網路上傳輸的時候不能直接傳輸二進位,而一般使用xml進行傳輸,xml裡面仍然不能寫入位元據,但我們可以通過把位元據轉換為Base64的編碼形式,而Base64的字串是可以儲存在xml檔案中的。當xml資料檔案傳輸到對方之後,對方再用逆向的方法把Base64的String轉換為二進位,再進行解密。

運行結果

我們的設定檔中可以把連接字串加密存入設定檔,然後使用的時候解密,這樣能提高程式的安全性。

在擷取連接字串時用同樣的密鑰"NorthwindKey"進行解密

但是我們也最好不要把密鑰和解密演算法放在程式中,因為可以通過反編譯看出加密規則。我們可以通過把密鑰放在註冊表中,或者通過加密狗等程式來提高安全性。

 

Code Access Security

最低許可權的策略

讓所有使用者具有最低許可權。

Code Group——按照邏輯分類的程式碼群組合

Code Group可以按照多種方式劃分URL,string name,zone,etc

Permission Sets——許可集,用來定義代碼能夠訪問的資源:檔案I/O,Isolated Storage隔離儲存區 (Isolated Storage),SQL用戶端,等等。

Link demands

 

示範四

代碼訪問安全

我們可以用這樣的代碼來保證我們的應用程式在啟動並執行時候一定要具有某些許可權才可以運行。應用程式本身可以檢測當前Windows作業系統上的.NET架構配置上面是否允許運行。例如,WebPermission表示要求電腦要能訪問Web。IsolatedStorage標籤表示需要有能夠訪問隔離儲存區 (Isolated Storage)的功能。

Refused set表示要拒絕的功能。

進入cmd,在當前工程的路徑,我們可以通過permview命令來觀看當前應用程式集需要什麼樣的許可權。

我們也可以在組態工具中的Code Group來劃分許可權,以及設定PermissionSet

 

強命名應用程式集

使用sn.exe工具來建立強命名公開金鑰/私密金鑰對,並儲存在檔案當中:

sn.exe –k Northwind.snk

sn是strong name的縮寫,我們可以用-k的方式,後面帶密鑰檔案名稱,產生一個公開金鑰/私密金鑰對。編譯器的簽名工具會利用私密金鑰對程式集加密,產生密碼編譯摘要,放在Manifest中,並在Manifest中存放公開金鑰,在運行程式集時,會拿到公開金鑰資訊,驗證簽名是否有效。

AssemblyKeyFileAttribute

可以在AssemblyInfo中的這個標籤來標記密鑰檔案的路徑

優勢

可以被裝在到GAC當中

Side-by-side部署,支援多個版本的應用程式集

在編譯時間,.NET的用戶端代碼使用了強命名應用程式集,在運行時能夠有效地防止裝入“木馬”應用程式集。其他人雖然可以反編譯或者修改我們的代碼,但是他們不具有我們的私密金鑰檔案,在使用dll的時候,程式會檢測dll是否具有強命名,如果不具有,程式是不會理會的。

 

Delayed Signing

私密金鑰保密性,確保Team Dev中的多個組建使用相同的強命名

如果我們的Team Dev很龐大,我們如果想讓團隊的人對項目進行強命名,我們就需要把密鑰檔案給他,這就相當於把私密金鑰給他了。這種方式是很危險的,我們不能保證每個開發人員都是效忠的。我們可以使用下面的方法。

只匯出公開金鑰

我們讓所有程式員在開發的時候,唯寫上只包含公開金鑰的snk地址,然後我們加入標籤AssemblyDelaySign(True),這樣在真正用私密金鑰加密之後的簽名不會在每一次產生都放到dll中。

Sn -Vr<assemblyname>:關閉對只擁有公開金鑰的強命名應用程式集進行驗證

Sn –R<assemblyname><keyfilename>:在發布之前對應用程式集進行緩簽名

在發布之前才對所有程式進行真正的簽名

 

Link Demands

串連請求發生在外部的代碼對本應用程式集進行調用的時候

System.Security.Permissions名稱空間

例如:StrongNameIdentityPermission屬性

從某個應用程式集中提取公開金鑰標示(一個十六進位的字元序列)

sn –Tp NorthwindModel.dll

例如:

這個標籤要求別的應用程式集在裝載我們程式集時,必須具有這種公開金鑰才可以,如果不是這種認證簽名的程式,將不會被允許串連到我們程式集內部。

例如如果我們想查看某個強命名的程式集公開金鑰的Token。

我們只要把這個標示填充到標籤中的PublicKey屬性即可。

 

Middle Tier安全

最現成的方法,COM+是最安全的解決方案——與Windows整合并支援配置

Web Service的安全可以通過HTTPS和IIS安全來控制

當不能使用IIS安全的時候,可以使用WS-Security(Web Service Enhancements的一部分)來保證平台之間的Web Service安全

Remoting安全

IIS宿主和TCP,使用IIS安全和HTTPS

其他宿主,需要實現定製的Channel或Sink

示範五

中介層安全

IIS安全,是預設的匿名的驗證,是Basic驗證

其中Cache添加的時候註明了是使用Basic驗證。這種驗證會將使用者名稱和密碼以明文的方式傳輸到IIS上面,所以我們在使用Basic驗證時應該最好使用Https來保證傳輸安全。

 

SQL注入

SQL注入這種威脅發生在動態產生SQL查詢語句的時候,動態產生的SQL語句可能會被篡改

例如:

如果在上面的SQL語句中加入'OR 1=1'這個條件,users表中的所有資料將作為結果返回

所有使用動態SQL查詢的應用程式都有可能受到這種威脅

為了防禦這種攻擊,去掉所有的動態SQL查詢:使用ADO.NET中的SqlParameters

 

示範六

防止SQL注入攻擊

上面是危險的方式,下面是安全的方式

注入攻擊

如果是第一種方式的代碼,那麼登入始終會成功,但如果是用第二種方式,登陸就會失敗。

 

安全設計目標

最小化攻擊範圍

分析具體的攻擊並阻止它們:

拒絕服務的攻擊

基於檔案或目錄的攻擊

SQL注入

引誘攻擊(Luring)

防患於未然,提早預知新的攻擊

使用經過驗證的安全技術:身分識別驗證,給予角色的授權,HTTPS,加密

 

總結

.NET包括了強大的內建的安全特性

具體問題具體分析,根據情況來選擇安全技術,編寫安全的基於Windows Forms的代碼

不需要絞盡腦汁去發明新的安全的程式碼

2010.10.20

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.