用ASP.NET加密Cookie資料

來源:互聯網
上載者:User
用ASP.NET加密Cookie資料

唐進華

2003-1-21 13:34:54

Cookie確實在WEB應用方面為訪問者和編程者都提供了方便,然而從安全方面考慮是有問題的,首先,Cookie資料包含在HTTP請求和響應的包頭裡透明地傳遞,也就是說聰明的人是能清清楚楚看到這些資料的

。其次,Cookie資料以Cookie檔案格式儲存在瀏覽者電腦的cache目錄裡,其中就包含有關網頁、密碼和其他使用者行為的資訊,那麼只要進入硬碟就能開啟Cookie檔案。圖1是一個Cookie檔案的內容:

如果你未曾留意你的機器裡有Cookie檔案,可以按下列方法查看:開啟IE,選擇“工具”菜單裡的“Internet選項”,然後在彈出的對話方塊裡點擊“設定”按鈕,在設定對話方塊裡點擊“查看”鈕,就會開啟一個視窗顯示瀏覽器放在硬碟裡的所有快取資料,其中就有大量的Cookie檔案。

所以奉勸大家不要將敏感的使用者資料存放在Cookie中,要麼就通過加密將這些資料保護起來。

在以前的ASP版本中沒有加密的功能,現在.NET構架在System.Security.Cryptography命名空間裡提供了許多加密類可以利用。

一、.NET的密碼系統概要

簡單地說,加密就是將原始字元(位元組)串轉變為完全不同的字串的處理過程,達到原始字元無法破譯的目的。這個處理過程是用另一個字串(稱為“密鑰”),採取複雜的、混合的演算法,“搗進”原始字串。有時還使用一個稱為“初始向量”的字串,在密鑰搗進之前先打亂目標字串,預防目標字串中較明顯的內容被識破。加密的功效取決於所用密鑰的大小,密鑰越長,保密性越強。典型的密鑰長度有64位、128位、192位、256位和512位。攻擊者唯一的方法是建立一個程式嘗試每一個可能的密鑰組合,但64位密鑰也有72,057,594,037,927,936種組合。

目前有兩種加密方法:對稱式加密(或稱私人密鑰)和非對稱式加密(或稱公用密鑰)。對稱式加密技術的資料交換兩邊(即加密方和解密方)必須使用一個保密的私人密鑰。非對稱式加密技術中,解密方向加密方要求一個公用密鑰,加密方在建立一個公用密鑰給解密方後,用公用密鑰建立唯一的私人密鑰。加密方用私人祕密金鑰加密送出的資訊,對方用公用密鑰解密。保護HTTP傳輸安全的SSL就是使用非對稱技術。

我們對Cookie資料的加密採取對稱式加密法。.NET構架從基本的SymmetricAlgorithm類擴充出來四種演算法:

·System.Security.Cryptography.DES

·System.Security.Cryptography.TripleDES

·System.Security.Cryptography.RC2

·System.Security.Cryptography.Rijndael

下面將示範DES和TripleDES演算法。DES的密鑰大小限制在64位,但用於Cookie的加密是有效。TripleDES完成了三次加密,並有一個較大的密鑰位元,所以它更安全。使用那一種演算法不僅要考慮加密強度,還要考慮Cookie的大小。因為加密後的Cookie資料將變大,並且,密鑰越大,加密後的資料就越大,然而Cookie資料的大小限制在4KB,這是一個必須考慮的問題。再者,加密的資料越多或演算法越複雜,就會佔有更多的伺服器資源,進而減慢整個網站的訪問速度。

二、建立一個簡單的加密應用類

.NET的所有加密和解密通過CryptoStream類別來處理,它衍生自System.IO.Stream,將字串作為以資料流為基礎的模型,供加密轉換之用。下面是一個簡單的加密應用類的代碼:

Imports System.Diagnostics

Imports System.Security.Cryptography

Imports System.Text

Imports System.IO

Public Class CryptoUtil

'隨機選8個位元組既為密鑰也為初始向量

Private Shared KEY_64() As Byte = {42, 16, 93, 156, 78, 4, 218, 32}

Private Shared IV_64() As Byte = {55, 103, 246, 79, 36, 99, 167, 3}

'對TripleDES,採取24位元組或192位的密鑰和初始向量

Private Shared KEY_192() As Byte = {42, 16, 93, 156, 78, 4, 218, 32, _

15, 167, 44, 80, 26, 250, 155, 112, _

2, 94, 11, 204, 119, 35, 184, 197}

Private Shared IV_192() As Byte = {55, 103, 246, 79, 36, 99, 167, 3, _

42, 5, 62, 83, 184, 7, 209, 13, _

145, 23, 200, 58, 173, 10, 121, 222}

'標準的DES加密

Public Shared Function Encrypt(ByVal value As String) As String

If value <> "" Then

Dim cryptoProvider As DESCryptoServiceProvider = _

New DESCryptoServiceProvider()

Dim ms As MemoryStream = New MemoryStream()

Dim cs As CryptoStream = _

New CryptoStream(ms, cryptoProvider.CreateEncryptor(KEY_64, IV_64), _

CryptoStreamMode.Write)

Dim sw As StreamWriter = New StreamWriter(cs)

sw.Write(value)

sw.Flush()

cs.FlushFinalBlock()

ms.Flush()

'再轉換為一個字串

Return Convert.ToBase64String(ms.GetBuffer(), 0, ms.Length)

End If

End Function

'標準的DES解密

Public Shared Function Decrypt(ByVal value As String) As String

If value <> "" Then

Dim cryptoProvider As DESCryptoServiceProvider = _

New DESCryptoServiceProvider()

'從字串轉換為位元組組

Dim buffer As Byte() = Convert.FromBase64String(value)

Dim ms As MemoryStream = New MemoryStream(buffer)

Dim cs As CryptoStream = _

New CryptoStream(ms, cryptoProvider.CreateDecryptor(KEY_64, IV_64), _

CryptoStreamMode.Read)

Dim sr As StreamReader = New StreamReader(cs)

Return sr.ReadToEnd()

End If

End Function

'TRIPLE DES加密

Public Shared Function EncryptTripleDES(ByVal value As String) As String

If value <> "" Then

Dim cryptoProvider As TripleDESCryptoServiceProvider = _

New TripleDESCryptoServiceProvider()

Dim ms As MemoryStream = New MemoryStream()

Dim cs As CryptoStream = _

New CryptoStream(ms, cryptoProvider.CreateEncryptor(KEY_192, IV_192), _

CryptoStreamMode.Write)

Dim sw As StreamWriter = New StreamWriter(cs)

sw.Write(value)

sw.Flush()

cs.FlushFinalBlock()

ms.Flush()

'再轉換為一個字串

Return Convert.ToBase64String(ms.GetBuffer(), 0, ms.Length)

End If

End Function

'TRIPLE DES解密

Public Shared Function DecryptTripleDES(ByVal value As String) As String

If value <> "" Then

Dim cryptoProvider As TripleDESCryptoServiceProvider = _

New TripleDESCryptoServiceProvider()

'從字串轉換為位元組組

Dim buffer As Byte() = Convert.FromBase64String(value)

Dim ms As MemoryStream = New MemoryStream(buffer)

Dim cs As CryptoStream = _

New CryptoStream(ms, cryptoProvider.CreateDecryptor(KEY_192, IV_192), _

CryptoStreamMode.Read)

Dim sr As StreamReader = New StreamReader(cs)

Return sr.ReadToEnd()

End If

End Function

End Class

上面我們將一組位元組初始化為密鑰,並且使用的是數字常量,如果你在實際應用中也這樣做,這些位元組一定要在0和255之間,這是一個位元組允許的範圍值。

三、建立一個Cookie的應用類

下面我們就建立一個簡單的類,來設定和擷取Cookies。

Public Class CookieUtil

'設定COOKIE *****************************************************

'SetTripleDESEncryptedCookie (只針對密鑰和Cookie資料)

Public Shared Sub SetTripleDESEncryptedCookie(ByVal key As String, _

ByVal value As String)

key = CryptoUtil.EncryptTripleDES(key)

value = CryptoUtil.EncryptTripleDES(value)

SetCookie(key, value)

End Sub

'SetTripleDESEncryptedCookie (增加了Cookie資料的有效期間參數)

Public Shared Sub SetTripleDESEncryptedCookie(ByVal key As String, _

ByVal value As String, ByVal expires As Date)

key = CryptoUtil.EncryptTripleDES(key)

value = CryptoUtil.EncryptTripleDES(value)

SetCookie(key, value, expires)

End Sub

'SetEncryptedCookie(只針對密鑰和Cookie資料)

Public Shared Sub SetEncryptedCookie(ByVal key As String, _

ByVal value As String)

key = CryptoUtil.Encrypt(key)

value = CryptoUtil.Encrypt(value)

SetCookie(key, value)

End Sub

'SetEncryptedCookie (增加了Cookie資料的有效期間參數)

Public Shared Sub SetEncryptedCookie(ByVal key As String, _

ByVal value As String, ByVal expires As Date)

key = CryptoUtil.Encrypt(key)

value = CryptoUtil.Encrypt(value)

SetCookie(key, value, expires)

End Sub

'SetCookie (只針對密鑰和Cookie資料)

Public Shared Sub SetCookie(ByVal key As String, ByVal value As String)

'編碼部分

key = HttpContext.Current.Server.UrlEncode(key)

value = HttpContext.Current.Server.UrlEncode(value)

Dim cookie As HttpCookie

cookie = New HttpCookie(key, value)

SetCookie(cookie)

End Sub

'SetCookie(增加了Cookie資料的有效期間參數)

Public Shared Sub SetCookie(ByVal key As String, _

ByVal value As String, ByVal expires As Date)

'編碼部分

key = HttpContext.Current.Server.UrlEncode(key)

value = HttpContext.Current.Server.UrlEncode(value)

Dim cookie As HttpCookie

cookie = New HttpCookie(key, value)

cookie.Expires = expires

SetCookie(cookie)

End Sub

'SetCookie (只針對HttpCookie)

Public Shared Sub SetCookie(ByVal cookie As HttpCookie)

HttpContext.Current.Response.Cookies.Set(cookie)

End Sub

'擷取COOKIE *****************************************************

Public Shared Function GetTripleDESEncryptedCookieValue(ByVal key As String) _

As String

'只對祕密金鑰加密

key = CryptoUtil.EncryptTripleDES(key)

'擷取Cookie值

Dim value As String

value = GetCookieValue(key)

'解密Cookie值

value = CryptoUtil.DecryptTripleDES(value)

Return value

End Function

Public Shared Function GetEncryptedCookieValue(ByVal key As String) As String

'只對祕密金鑰加密

key = CryptoUtil.Encrypt(key)

'擷取Cookie值

Dim value As String

value = GetCookieValue(key)

'解密Cookie值

value = CryptoUtil.Decrypt(value)

Return value

End Function

Public Shared Function GetCookie(ByVal key As String) As HttpCookie

'編碼密鑰

key = HttpContext.Current.Server.UrlEncode(key)

Return HttpContext.Current.Request.Cookies.Get(key)

End Function

Public Shared Function GetCookieValue(ByVal key As String) As String

Try

'編碼在GetCookie裡完成

'擷取Cookie值

Dim value As String

value = GetCookie(key).Value

'解碼所儲存的值

value = HttpContext.Current.Server.UrlDecode(value)

Return value

Catch

End Try

End Function

End Class

上面的設定功能中,有些功能附加提供了Cookie有效期間這個參數。不設定該參數,Cookie將只為瀏覽器會話才儲存在記憶體中。為了設定永久的Cookie,就需要設定有效期間參數。

上面我們對密鑰和Cookies值進行了編碼與解碼,其原因是Cookies與URLs有同樣的限制,字元“=”和“;”是保留的,不能使用。這在儲存加密後的資料時尤其重要,因為密碼編譯演算法將添加“=”,按所分配塊的大小來填滿該資料區塊。

好了,你會保護Cookies資料了吧?

(網頁編輯:編程浪子)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.