国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

ASP.NET Forms Authentication所生成Cookie的安全性

2024-07-10 12:56:08
字體:
供稿:網(wǎng)友



原創(chuàng) by fancyf(fancyray)

    我做這個(gè)實(shí)驗(yàn)是因?yàn)閔ttp://community.csdn.net/expert/topic/3927/3927012.xml?temp=.3752405
    最初我想,.net的驗(yàn)證應(yīng)該是比較安全的吧,生成的cookie也應(yīng)該與這臺(tái)電腦的獨(dú)特的參數(shù)相關(guān),拿到另一臺(tái)電腦上就應(yīng)該無效了。那么是不是一個(gè)用戶名對應(yīng)一個(gè)cookie值呢?是否能夠通過偽造cookie值來騙過表單驗(yàn)證呢?做一番試驗(yàn)。
    web.config修改如下:
    <authentication mode="forms">
  <forms name="mylab" loginurl="/login.aspx">
   <credentials passwordformat="clear">
    <user name="fancyray" password="fancyray"/>
   </credentials>
  </forms>
    </authentication>

    <authorization>
        <deny users="?" />
    </authorization>

    login.aspx只有一個(gè)用戶名輸入框txtusername、一個(gè)密碼輸入框txtpassword和一個(gè)提交按鈕,click事件如下:
if (formsauthentication.authenticate(this.txtusername.text, this.txtpassword.text))
{
 formsauthentication.redirectfromloginpage(this.txtusername.text, true);
}
else
{
 response.write("login denied");
}
    借助iehttpheaders(http://www.blunck.info/)可以看到,通過驗(yàn)證后增加了一個(gè)類似這樣的cookie:
mylab=3ff83247c29eb5d14d61f389d453eee0586b94e27609c321b017be7b88d1a94d249996428a7a18f5c2d69f3c4dd2b88c00172cafb0b4b4ed8784db62d1d61bcc0c786b4ea7868fc6
    看來這就是加密以后的cookie了。下面要換一臺(tái)電腦,直接將這個(gè)值設(shè)置為cookie,看看是否需要forms驗(yàn)證。
    在login.aspx頁面中加上這樣一句話:
     <script language=javascript>
 document.cookie="mylab=3ff83247c29eb5d14d61f389d453eee0586b94e27609c321b017be7b88d1a94d249996428a7a18f5c2d69f3c4dd2b88c00172cafb0b4b4ed8784db62d1d61bcc0c786b4ea7868fc6";
 </script>
    這樣只要一打開login.aspx頁面就會(huì)自動(dòng)加入這個(gè)cookie。
    另一臺(tái)電腦:輸入同一個(gè)webapplication下的另外一個(gè)頁面(應(yīng)該會(huì)自動(dòng)跳轉(zhuǎn)到login.aspx頁面)http://10.0.0.7/upload.aspx,這時(shí)成功跳轉(zhuǎn)到了http://10.0.0.7/login.aspx?returnurl=%2fupload.aspx,正常。這時(shí)cookie的值應(yīng)該已經(jīng)生效了。那么我們再輸入剛才那個(gè)頁面的網(wǎng)址http://10.0.0.7/upload.aspx!
    按照我的猜想,肯定還會(huì)跳到login.aspx頁面的,因?yàn)槟莻€(gè)cookie是在另一臺(tái)電腦上生成的。實(shí)際呢,沒有跳轉(zhuǎn)!完整地顯示出了upload.aspx的內(nèi)容!而我們根本沒有在這臺(tái)電腦上登錄,甚至我們連用戶名都不知道!
    我回到10.0.0.7這臺(tái)電腦在upload.aspx頁面的page_load()第一行添了一句:response.write(user.identity.name);,在另一臺(tái)電腦上刷新顯示出來了的upload.aspx,結(jié)果也出現(xiàn)了fancyray,正是我的用戶名。
    這說明,cookie的加密不依賴于登錄的電腦。也就是說,一旦你的cookie被別人獲得,他就有可能獲得你在這臺(tái)服務(wù)器上的權(quán)限。
    那么cookie的這個(gè)值是怎么來的呢?黑客是否可能不通過窮舉就得到這個(gè)值呢?


    我們先來看看cookie中到底存儲(chǔ)了一些什么,以及怎樣進(jìn)行的加密。reflactor(http://www.aisto.com/roeder/dotnet)上場!
public static void setauthcookie(string username, bool createpersistentcookie, string strcookiepath)
{
      formsauthentication.initialize();
      httpcontext.current.response.cookies.add(formsauthentication.getauthcookie(username, createpersistentcookie, strcookiepath));
}

public static httpcookie getauthcookie(string username, bool createpersistentcookie, string strcookiepath)
{
      formsauthentication.initialize();
      if (username == null)
      {
            username = "";
      }
      if ((strcookiepath == null) || (strcookiepath.length < 1))
      {
            strcookiepath = formsauthentication.formscookiepath;
      }
      formsauthenticationticket ticket1 = new formsauthenticationticket(1, username, datetime.now, createpersistentcookie ? datetime.now.addyears(50) : datetime.now.addminutes((double) formsauthentication._timeout), createpersistentcookie, "", strcookiepath);
      string text1 = formsauthentication.encrypt(ticket1);
      formsauthentication.trace("ticket is " + text1);
      if ((text1 == null) || (text1.length < 1))
      {
            throw new httpexception(httpruntime.formatresourcestring("unable_to_encrypt_cookie_ticket"));
      }
      httpcookie cookie1 = new httpcookie(formsauthentication.formscookiename, text1);
      cookie1.path = strcookiepath;
      cookie1.secure = formsauthentication._requiressl;
      if (ticket1.ispersistent)
      {
            cookie1.expires = ticket1.expiration;
      }
      return cookie1;
}
    cookie中存儲(chǔ)的值就是里面的text1,text1是由string text1 = formsauthentication.encrypt(ticket1);生成的,所以text1里面的信息就是ticket1了。formsauthenticationticket的構(gòu)造函數(shù)原形為:
public formsauthenticationticket(int version, string name, datetime issuedate, datetime expiration, bool ispersistent, string userdata, string cookiepath)
    里面有用戶名、生成ticket1的時(shí)間和過期時(shí)間。
    看到這里我不禁打了一個(gè)冷顫。ticket1實(shí)際上只用到了用戶名一個(gè)關(guān)鍵信息,連密碼都沒有用!這樣豈不是任何一個(gè)用戶的ticket1都可以輕易的制造出來嗎?只要通過formsauthentication.encrypt(ticket1)就得到了cookie的值,來偽裝成任何一個(gè)用戶?太可怕了。現(xiàn)在只能寄希望于encrypt這個(gè)函數(shù)了。看看它的實(shí)現(xiàn):
public static string encrypt(formsauthenticationticket ticket)
{
      if (ticket == null)
      {
            throw new argumentnullexception("ticket");
      }
      formsauthentication.initialize();
      byte[] buffer1 = formsauthentication.maketicketintobinaryblob(ticket);
      if (buffer1 == null)
      {
            return null;
      }
      if (formsauthentication._protection == formsprotectionenum.none)
      {
            return machinekey.bytearraytohexstring(buffer1, 0);
      }
      if ((formsauthentication._protection == formsprotectionenum.all) || (formsauthentication._protection == formsprotectionenum.validation))
      {
            byte[] buffer2 = machinekey.hashdata(buffer1, null, 0, buffer1.length);
            if (buffer2 == null)
            {
                  return null;
            }
            formsauthentication.trace("encrypt: mac length is: " + buffer2.length);
            byte[] buffer3 = new byte[buffer2.length + buffer1.length];
            buffer.blockcopy(buffer1, 0, buffer3, 0, buffer1.length);
            buffer.blockcopy(buffer2, 0, buffer3, buffer1.length, buffer2.length);
            if (formsauthentication._protection == formsprotectionenum.validation)
            {
                  return machinekey.bytearraytohexstring(buffer3, 0);
            }
            buffer1 = buffer3;
      }
      buffer1 = machinekey.encryptordecryptdata(true, buffer1, null, 0, buffer1.length);
      return machinekey.bytearraytohexstring(buffer1, buffer1.length);
}
 
    看到了machinekey這個(gè)詞,終于松了一口氣。看來加解密過程是與服務(wù)器的參數(shù)有關(guān)系。也就是說,服務(wù)器上有自己的密鑰,只有用這個(gè)密鑰才能進(jìn)行cookie的加解密。如果不知道這個(gè)密鑰,別人是無法偽造cookie的。

    看來cookie還是安全的,在你的電腦沒有被入侵的前提下。與其他任何信息一樣,所需注意的僅僅是網(wǎng)絡(luò)傳輸中的安全性了。
    cookie的這個(gè)值和sessionid一樣,都是一旦被猜中就可能引發(fā)安全問題。但又與sessionid有區(qū)別,因?yàn)閟essionid總是短暫的,而cookie的值卻有可能是永遠(yuǎn)有效的。cookie值的長度也讓我們稍稍放了一點(diǎn)心。

    還有一個(gè)問題不容忽視。雖然cookie的值的生成與具體的時(shí)間有關(guān),也就是我注銷后再次登陸所生成的cookie是不一樣的,但是一個(gè)合法的cookie值是永久有效的,不受是否改變密碼及時(shí)間的影響。也就是說,我上一次生成的cookie在我注銷以后拿到另一臺(tái)電腦上仍然可以用,只要服務(wù)器的machinekey不變。的確是個(gè)安全隱患。我們也只能說:“cookie的值很長,要窮舉到一個(gè)有效的cookie在有生之年是辦不到的”來找一些安慰。密碼可以通過頻繁的更改來進(jìn)一步減小窮舉到的可能性,但合法的cookie卻無法更改。密碼是唯一的,但合法的cookie值卻不是唯一的。這一切總讓人覺得不太放心。
    也許擔(dān)心是多余的,因?yàn)殡娮雍灻⒆C書都是建立在“窮舉要付出很大代價(jià)”的基礎(chǔ)上的,要是考慮“碰巧被窮舉到”的話,安全就不復(fù)存在了。相信在一般的安全領(lǐng)域,forms生成的cookie的安全級別還是足夠的。
    放心地去用吧!(又一篇毫無價(jià)值的文章,當(dāng)你沒看過好了)
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 碌曲县| 商河县| 衡阳市| 凌云县| 梨树县| 磴口县| 汽车| 哈巴河县| 晋宁县| 南汇区| 达孜县| 台北市| 杂多县| 大竹县| 栖霞市| 普兰店市| 冀州市| 柳林县| 延川县| 治县。| 泰州市| 沁水县| 丹棱县| 宜宾市| 行唐县| 张家港市| 叶城县| 新巴尔虎右旗| 济宁市| 虎林市| 固镇县| 渝中区| 镇康县| 大理市| 衡阳县| 唐山市| 富蕴县| 石楼县| 三原县| 丹东市| 铁力市|