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,将字元串作為以資料流為基礎的模型,供加密轉換之用。下面是一個簡單的加密應用類的代碼:
importssystem.diagnostics
importssystem.security.cryptography
importssystem.text
importssystem.io
publicclasscryptoutil
'随機選8個位元組既為密鑰也為初始向量
privatesharedkey_64()asbyte={42,16,93,156,78,4,218,32}
privatesharediv_64()asbyte={55,103,246,79,36,99,167,3}
'對tripledes,采取24位元組或192位的密鑰和初始向量
privatesharedkey_192()asbyte={42,16,93,156,78,4,218,32,_
15,167,44,80,26,250,155,112,_
2,94,11,204,119,35,184,197}
privatesharediv_192()asbyte={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加密
publicsharedfunctionencrypt(byvalvalueasstring)asstring
ifvalue<>""then
dimcryptoproviderasdescryptoserviceprovider=_
newdescryptoserviceprovider()
dimmsasmemorystream=newmemorystream()
dimcsascryptostream=_
newcryptostream(ms,cryptoprovider.createencryptor(key_64,iv_64),_
cryptostreammode.write)
dimswasstreamwriter=newstreamwriter(cs)
sw.write(value)
sw.flush()
cs.flushfinalblock()
ms.flush()
'再轉換為一個字元串
returnconvert.tobase64string(ms.getbuffer(),0,ms.length)
endif
endfunction
'标準的des解密
publicsharedfunctiondecrypt(byvalvalueasstring)asstring
'從字元串轉換為位元組組
dimbufferasbyte()=convert.frombase64string(value)
dimmsasmemorystream=newmemorystream(buffer)
newcryptostream(ms,cryptoprovider.createdecryptor(key_64,iv_64),_
cryptostreammode.read)
dimsrasstreamreader=newstreamreader(cs)
returnsr.readtoend()
'tripledes加密
publicsharedfunctionencrypttripledes(byvalvalueasstring)asstring
dimcryptoproviderastripledescryptoserviceprovider=_
newtripledescryptoserviceprovider()
newcryptostream(ms,cryptoprovider.createencryptor(key_192,iv_192),_
'tripledes解密
publicsharedfunctiondecrypttripledes(byvalvalueasstring)asstring
newcryptostream(ms,cryptoprovider.createdecryptor(key_192,iv_192),_
endclass
上面我們将一組位元組初始化為密鑰,并且使用的是數字常量,如果你在實際應用中也這樣做,這些位元組一定要在0和255之間,這是一個位元組允許的範圍值。
三、建立一個cookie的應用類
下面我們就建立一個簡單的類,來設定和擷取cookies。
publicclasscookieutil
'設定cookie*****************************************************
'settripledesencryptedcookie(隻針對密鑰和cookie資料)
publicsharedsubsettripledesencryptedcookie(byvalkeyasstring,_
byvalvalueasstring)
key=cryptoutil.encrypttripledes(key)
value=cryptoutil.encrypttripledes(value)
setcookie(key,value)
endsub
'settripledesencryptedcookie(增加了cookie資料的有效期參數)
byvalvalueasstring,byvalexpiresa