日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何实现一个安全的Web登陆

發(fā)布時間:2023/12/16 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何实现一个安全的Web登陆 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

綜述:

待 Update:QUIC, SSO, HSTS等協(xié)議研究,SHA-1 可破解

總結(jié): 沒有絕對的安全,能不自己做就不自己做, 要么 openID(不了解), 要么OAuth(推薦QQ & Github)

本文不考慮鍵盤記錄器等養(yǎng)毒行為, 本文不考慮堆棧溢出, exploit, SQL注入等。 單純談?wù)撈虻顷憰掃^程

思維養(yǎng)成key: 時間, 信任

無解問題: CSRF, 中間人攻擊(有應(yīng)對方案,但沒有根本解決的方案)

SSL必加, 客戶端加密可選, localStorage 存 token(CSRF), 指紋ID:UUID(Java),cookie 設(shè)計Chrome Dev參考網(wǎng)站猜測大致保存用戶名,session, jsessionid, uuid, token(瀏覽器不支持localStorage), Hm_lvt_siteid(記錄訪客當(dāng)前訪問序列的開始時間,如果沒有設(shè)置這個cookie,則訪客為新訪客。當(dāng)本次訪問是一個新的訪問開始時,更新該cookie為當(dāng)前時間.), Hm_lpvt_siteid(當(dāng)前瀏覽頁面時的時間,每次瀏覽時設(shè)置該cookie為當(dāng)前時間)等

正文

09年老5則

  • 加密單向并且強(qiáng)壯(MD5我100個不推薦, 看刷ctf的整天口算md5玩, 看開頭,所以推薦 SHA2)

  • 密碼長度強(qiáng)制長

  • 密碼字符無限制, 至少滿足ascii(出開頭結(jié)束空格)

  • 不要給用戶發(fā)送他的密碼(VMware就這么蠢比過) IMAP 應(yīng)用,中間人攻擊 between the mail client and GMail

    • Anyone who had access to the network or SMTP systems involved in the hand-off chain between VMware’s systems and Google.
    • Anyone who has administrative access to Google’s email systems, including the eternal GMail backups.
    • Anyone capable of compromising the integrity of Google’s systems.
    • Anyone capable of compromising the integrity of my laptop.
    • Anyone who gains access to a public machine I was using after I forgot to log out of GMail.
  • OpenID 不適合作為安全的關(guān)鍵部分, 但大部分適用

  • 忠告: Don’t implement your own authentication system unless you absolutely have to

    總結(jié): 贊忠告,為啥不試試OAuth 2.0 操作之類的?我選 github & qq sdk

    初步探索

  • token, user_id, track ip

  • 產(chǎn)生一個隨機(jī)token發(fā)到客戶端作為cookie, 這個cookie 與 服務(wù)器做出匹配來確定用戶

  • 除非實現(xiàn)session策略或者網(wǎng)站分布在集群之類的,不要用數(shù)據(jù)庫存儲session

  • hash + salt 密碼加密, 打算加鹽(一個用戶一種鹽)防彩虹表?

  • Wiki

  • 認(rèn)證分兩部分: 登陸表單, per-request-check

  • 會話劫持

    • 方式:

    • 猜測

    • fixation: xss, 網(wǎng)絡(luò)嗅探

    • 應(yīng)對:

    • cookie設(shè)置 HTTP only。 可仿瀏覽器偽造,仿 js 注入

    • 樓上那個, 不好意思,可解

    • 登陸不僅僅依賴sessionid

    • session 時間, client指紋(一般是設(shè)備信息決定)變化, 登出請求 時銷毀cookie, 清理session

    • Note: 指紋舉例 fingerprint=hashhmac(sha256,_SERVER[‘HTTP_USER_AGENT’], hash(‘sha256’, $_SERVER[‘REMOTE_ADDR’], true));

    • SSL 是最好的仿白文傳送, 對比而言, 別用客戶端加密這個方法(因為劫持了就相當(dāng)于拿到了加密,加密本身也就沒了效果)

    • 所以要加密就在server端加密

    • 鹽的生成可以從加密來挑字符,關(guān)于鹽的長度: Even 4 random bytes of salt will increase the complexity of a rainbow table attack by a factor of 4 billion.

    • SSL 是必須的,無論如何這個都必須

    • Bcrypt

      Besides incorporating a salt to protect against rainbow table attacks, bcrypt is an adaptive function: over time, the iteration count can be increased to make it slower, so it remains resistant to brute-force search attacks even with increasing computation power…. Cryptotheoretically, this is no stronger than the standard Blowfish key schedule, but the number of rekeying rounds is configurable; this process can therefore be made arbitrarily slow, which helps deter brute-force attacks upon the hash or salt.

    • SSL安裝: 自己做個證書強(qiáng)迫用戶裝(又是12306), 買(阿里送了個1000元一年的, 想想都貴), let ‘s encrypt(免費 且 賊棒,crontab設(shè)置個90天內(nèi)翻新就行了)

    • 爆力攻擊減速, 如果失敗, 等待一定時間后返回失敗(考慮用戶體驗取舍,建議可加)

    • 慣用行為: 。。。。感覺這個太他媽難, 就是類似twitter那樣換個瀏覽器換個ip換個設(shè)備立馬曉得然后通知你

    • 驗證碼(CAPTCHA): 這是個用戶體驗很差的東西,想想12306? 總之做的有點意思或者大氣上檔次才行

  • 休息一下

    • 攻擊:堆棧溢出。 解決:防偽式編程, 驗證和過濾惡意輸入

    • 攻擊:留言,打倒GCD這種神奇操作。 解決: 茍利國家生死以,豈因福禍避趨之。 給他過掉

    • 錯誤:仿debug模式報異常等。 解決:控制好異常的邊界

    初步設(shè)計Cookie

  • Cookie 設(shè)計, 三個東西:

    • 用戶名

    • 登陸序列, 僅當(dāng)強(qiáng)制用戶輸入口令時更新

    • 登陸 token

    • 僅一個登錄Session內(nèi)有效

    • 新的登錄Session會更新它

    • 登錄Token是單實例登錄 Singleton

    • 當(dāng)前兩者正確,第三者卻不正確時(有人盜用更新了token)用戶回來訪問時不對,系統(tǒng)便清除登陸序列和token令cookie失效

  • 重要操作必須輸入口令, 比如支付, 改密信息之類的, 不能因cookie直接操作(大概想防XSS?)

  • 密保設(shè)定私人信息(比如你爸媽叫啥)有點白癡,因為可以社工之類的

  • 郵件重置較為安全, 根據(jù)用戶(uuid,timestamp,token等)生成MD5 url,并設(shè)定操作權(quán)限時間。

  • 系統(tǒng)操作封IP之類的, 凍結(jié)賬戶這種操作由用戶決定, 少做讓用戶反感的事

  • 重點:必看 Cookie 參數(shù)詳解

    CSRF Token

    • Token 保存

      • csrf token 保存在瀏覽器的localStorage, 不是cookie

      • 請求時利用 csrf token 作為鹽值, 每次請求的時候使用CsrfToken作為鹽值對參數(shù)進(jìn)行Md5簽名,網(wǎng)關(guān)從請求的Cookie中取出userToken并AES解密出CsrfToken,再進(jìn)行驗簽。用戶退出或者userToken時效的時候都會主動從LocalStorage中清除CsrfToken,從cookie中清除Token和用戶信息,任何需要訪問用戶登錄態(tài)的數(shù)據(jù)因為都需要加密,所以首先會判斷CsrfToken是否存在,不存在直接跳登錄頁了。

      • 這樣一來, 鹽值不參與請求, 只是加密用

      • 短信檢測考慮成本必加時限和圖片驗證

    • Token 可選位置

      • 驗證 HTTP Referrer 字段;(仿盜圖用也不錯,但可以手工修改,所以不是好方案)

      • 在請求地址中添加 token 并驗證, 表單生成帶token

      • 在 HTTP 頭中自定義屬性并驗證。

    • 總結(jié): CSRF 難解,可以說各有利弊,換句話說差不多就是解不了

    • Token 必知必會

    • Note: Ajax 同源, CORS 跨源, JSONP

    Demo

  • 數(shù)據(jù)結(jié)構(gòu)設(shè)計: 用戶數(shù)據(jù) 和 認(rèn)證分開存儲, 從而便于認(rèn)證擴(kuò)展

  • 驗證成功的token要更新

  • 客戶端加密公開, 所以要加密就加鹽,讓他推也難受

  • 實例示范:

  • 瀏覽器主要完成以下工作:

    獲取用戶輸入的用戶名及密碼
    通過輸入的用戶名和密碼,進(jìn)行哈希,得到瀏覽器端密文
    將用戶名和密文提交給后端

    // 密碼與用戶名的哈希 function encryptPwd(username, password) {username = username.toLowerCase();return sha256(username + sha256 (sha256(sha256(sha256(password))) + sha256(username))); }$scope.login = function(){// 檢查用戶名和密碼的合法性,比如是否輸入,長度是否足夠等if($scope.check()) {return;}$scope.successMessage = '';$scope.errorMessage = '';$scope.status = 'loading';// 向后端提交登錄請求$resource('/user/login').save({username: $scope.username,password: encryptPwd($scope.username, $scope.password)}, function(res){$scope.status = 'done';$scope.successMessage = 'login successful!';}, function(reason){$scope.status = 'done';$scope.errorMessage = reason.data || 'failed';}); };

    后端驗證:
    獲取前端提交的用戶名及瀏覽器端密文
    根據(jù)用戶名,在數(shù)據(jù)庫中查詢出對應(yīng)的鹽 id
    通過鹽 id 取出對應(yīng)的鹽,再通過用戶名、瀏覽器端密文和鹽算出后端密文
    根據(jù)用戶名和后端密文到用戶表查詢,如果有結(jié)果,則表明登錄信息正確,返回給瀏覽器登錄成功的響應(yīng)
    生成新的鹽,算出新的后端密文,并將兩者更新到數(shù)據(jù)庫中

    function encryptPwd(usr, pwd, salt){usr = usr.toLowerCase();return sha256(sha256(usr + sha256(pwd + salt)) + salt + sha256(usr + salt)) }function login(req, res, next){// 用戶名密碼獲取和檢查已省略// 根據(jù)用戶名,獲取鹽 idreq.models.user.findOne({select:['username', 'saltId'], where: {username: username}}).exec(function(err, userDoc){if(err) return next(err);if(!userDoc) return next(new Error('username not exists'));// 取鹽req.models.salt.findOne({id: userDoc.saltId}).exec(function(err, saltDoc){if(err) return next(err);if(!saltDoc) return next(new Error('can NOT find salt'));// 根據(jù)用戶名、密碼和鹽推算出密文var pwdHash = encryptPwd(username, password, saltDoc.salt);// 在數(shù)據(jù)庫中核對用戶名和密文req.models.user.findOne({select: ['id'], where: {username: username, password: pwdHash }}).exec(function(err, doc){if(err) return next(err);if(!doc) return next(new Error('password error'));res.json({username: username});return updateSalt(saltDoc, userDoc, password, next);});});}); }

    前面返回給用戶成功登錄的響應(yīng)之后,調(diào)用了更新鹽和密文的方法,該方法具體流程如下:

    生成并存儲新鹽
    根據(jù)新鹽、用戶名和瀏覽器端密文,生成新的后端密文
    存儲后端密文到用戶信息表

    function updateSalt(saltDoc, userDoc, passwordInputed, next){saltDoc.salt = Math.random().toString(15).substr(3, 27);saltDoc.save(function(err){if(err) return next(err);userDoc.password = encryptPwd(userDoc.username, passwordInputed, saltDoc.salt);userDoc.save(function(err){if(err) return next(err);return next();});}); }

    數(shù)據(jù)存儲這塊,使用了 Waterline 這個 ORM 中間件使用它的目的主要是為了將用戶信息和鹽存儲到不同的地方。本例中將鹽用 sails-disk 存儲到了文件中,用戶信息用 sails-mongo 存儲到了 MongoDB 中。

    后記

  • XSS & CSRF , SSRF 不考慮

    • 盜用 cookie ,獲取敏感信息。

    • 利用植入 Flash ,通過 crossdomain 權(quán)限設(shè)置進(jìn)一步獲取更高權(quán)限;或者利用Java等得到類似的操作。

    • 利用 iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻擊)用戶的身份執(zhí)行一些管理動作,或執(zhí)行一些一般的如發(fā)微博、加好友、發(fā)私信等操作。

    • 利用可被攻擊的域受到其他域信任的特點,以受信任來源的身份請求一些平時不允許的操作,如進(jìn)行不當(dāng)?shù)耐镀被顒印?/p>

    • 在訪問量極大的一些頁面上的XSS可以攻擊一些小型網(wǎng)站,實現(xiàn)DDoS攻擊的效果。

    • 防御: 過濾; Http制定頭類型, 避免被解析為html

  • TLS MITM 這玩意能解?

  • 參考鏈接:

    https://www.zhihu.com/question/20744215

    https://www.v2ex.com/t/161520

    • 一般能防MITM的要具有以下特征:

      1、握手加密而且具有可信CA(SSL、TLS之類,CNNIC和WoSign就不點評了)或擁有預(yù)協(xié)商密鑰(L2TP)

      2、加密方法足夠強(qiáng)大(AES、CHACHA20之類,RC4和SM2就不點評了)

    • 綜上,一般情況下,以下的協(xié)議是安全的:

      1、HTTPS(排除RC4、3DES算法,排除CNNIC、WoSign的CA證書)

      2、OpenVPN(基于TLS,只要你能連上就是安全的)

      3、L2TP Over IPSec(必須要Over IPSec,沒了就沒加密了)

      4、IKEv2(基于TLS和可信CA發(fā)的證書,安全性比OpenVPN還好)

      5、SSTP(基于TLS和可信CA發(fā)的證書,安全性和IKEv2相同,穩(wěn)定性加強(qiáng),用443端口)

      6、ShadowSocks(基于N+1種加密算法,只要你不選RC4或RC4-MD5算法就是安全的)

      7、任何用SSL Stream過又驗證CA甚至客戶端證書的TCP連接(UDP大家都懂,DNS什么的)

    總結(jié)

    以上是生活随笔為你收集整理的如何实现一个安全的Web登陆的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。