簡體   English   中英

你能發現我的身份驗證協議中的漏洞嗎?

[英]Can you spot a vulnerability in my authentication protocol?

前段時間我們需要一個多個Web服務之間的單點登錄身份驗證解決方案。 至少在那個時候我們認為OpenID協議過於復雜,我們不相信它的Ruby on Rails插件。 因此,我們設計了自己的協議,而不是實現OpenID提供者和OpenID使用者。

我有兩個問題:

  1. 不創建我們自己的OpenID提供商並設置我們的OpenID消費者只接受它是不是一件壞事嗎? 不允許公開登錄或注冊,我們希望簡化身份驗證。

  2. 您能否在以下設計中發現關鍵錯誤或漏洞?

如果你作為一個公社可以批准這個設計,我會考慮將這個代碼提取到Ruby on Rails插件中。

請查看流程圖和順序圖

細節:

身份驗證提供程序(“AP”):

  • 中央服務,包含有關用戶的所有數據。
  • 此設置中只存在一個“AP”。
  • 有可能有多個“AP”,但在這種情況下這不應該是相關的。
  • “AP”事先知道每個“S”。

身份驗證客戶端(服務“S”):

  • 存在多個內部和外部Web服務。
  • 每個服務事先都知道“AP”及其公鑰。

演員(“A”):

  • 通過用戶名和密碼使用AP對自己進行身份驗證的最終用戶
  • 可以在登錄前直接請求任何“S”或“AP”URI

“A”,“S”和“AP”之間的連接由HTTPS保護。

簡要描述了認證邏輯:

這些是對本文頂部鏈接的圖形流程圖和序列圖的描述。

1)Auth Provider“AP”

  • “AP”向“S”發出服務器到服務器HTTP POST請求以獲取現時。
  • “AP”生成身份驗證令牌。
  • 身份驗證令牌是一個XML實體,包括:
    • 到期日(從現在起2分鍾),
    • 先前請求的隨機數(以防止重播),
    • 識別“S”的名稱(Service_1的令牌不適合Service_2),
    • 有關最終用戶的信息。
  • 身份驗證令牌使用AES256加密,加密密鑰和初始化向量由AP的私有RSA密鑰簽名。
  • 產生的字符串(“data”,“key”和“iv”)首先進行Base64編碼,然后進行URL編碼,以允許它們在URL查詢字符串中傳遞。
  • 最終用戶“A”被HTTP重定向到服務“S”(HTTPS GET請求)。

2)服務“S”

  • 從用戶代理接收URL參數中的身份驗證令牌。
  • 使用AP的預共享公鑰解密身份驗證令牌。
  • 僅接受一次身份驗證令牌(令牌包含僅一次有效的nonce)。
  • 檢查身份驗證令牌中的標識名稱是否與服務名稱相對應。
  • 檢查身份驗證令牌是否已過期。

備注:

如果其他人也可以解密身份驗證令牌,這不是問題,因為它不包含有關用戶的機密信息。 但是,除AP之外的其他任何人都無法生成有效的身份驗證令牌。 因此涉及RSA密鑰對。

RSA私鑰僅用於對令牌進行簽名,因為它無法加密比實際密鑰長度更長的數據。 因此,AES用於加密。

由於身份驗證令牌是作為HTTP GET請求傳遞的,因此它將存儲在例如Apache的日志文件中。 使用一次性隨機數和失效日期應盡量減少重放攻擊的可能性。 POST請求需要一個HTML頁面,其中包含由Javascript自動提交的表單,這就是使用GET的原因。

服務“S”僅在服務器到服務器API請求中生成隨機數。 因此,未經身份驗證的生成請求不應構成DoS漏洞。

您會混淆身份驗證(“我就是我說的是我”)和授權/訪問控制(“我可以訪問它”)。 您只需實施OAuth,然后通過HTTPS查詢服務器“是否允許此OAuth身份訪問我?”。 您不必擔心重放攻擊,因為您使用的是HTTPS。

“安全很難,所以我會自己設計。”

身份驗證令牌使用AES256加密,加密密鑰和初始化向量由AP的私有RSA密鑰簽名。

AES-256和AES-192具有弱密鑰時間表。 但你不是用它來保密; 你正在使用它作為某種“完整性”檢查。 它不起作用:攻擊者獲得“簽名”身份驗證令牌。 攻擊者恢復了密鑰和IV。 攻擊者使用相同的密鑰和IV加密不同的身份驗證令牌,並使用相同的“簽名”。

散列它並簽署哈希有什么問題? 另請注意,如果您要使用自定義簽名,則需要注意填充(IIRC PKCS-無論添加至少11個字節)。

編輯:如果您使用的密碼應該使用散列/ MAC,那么您真的不應該設計安全協議!

以下是關於問題1的一些快速思考:

  • 設計一個有效的安全協議是非常困難的,所以基於一般原則,我傾向於使用現有協議。

  • 但是,我很欣賞OpenID當時可能還不是很成熟。 此外,OpenID仍然相對較新,可能尚未解決所有限制。

  • 盡管如此,你仍然在一個受限制的情況下使用OpenID,其中OpenID的大問題(多個參與者的參與)沒有發揮作用。 您只使用OpenID的“技術核心”,這更容易理解。

  • 您的要求和協議概述讓我想起了Kerberos。 我也很想推動LDAP +單點登錄,但我不知道具體的解決方案是什么。

  • 贊成你的協議的一點是你花時間詳細描述它。 只是這使你超過大多數自制的安全協議設計師!

簡而言之,我發現這個協議在錯誤的地方過度設計,最終容易受到攻擊。

那么什么是漏洞?

最終用戶“A”被HTTP重定向到服務“S”(HTTPS GET請求)。

這很可能違反了OWASP A9 用戶的會話ID在任何情況下都不能通過不安全的通道(例如http)傳遞。 即使會話ID尚未經過身份驗證,攻擊者仍然有耐心,他可以嗅探線路查找會話ID,然后定期檢查它們是否已經過身份驗證,然后使用它們訪問您的系統。

“復雜性是安全的最大敵人。”

- 布魯斯施奈爾

身份驗證令牌使用AES256加密,加密密鑰和初始化向量由AP的私有RSA密鑰簽名。

首先,RSA可用於加密消息,因此不需要。 另一方面,HTTPS將更有效並且被證明是安全的。 當您已經擁有安全的服務器到服務器通信通道時,我不明白為什么必須將身份驗證令牌傳遞給客戶端。 服務器可以說“嘿,有人被重定向到這個會話ID,他的狀態信息是什么?”。 這是鏈條中最薄弱的環節,你的會話ID應該足夠強大。 這將要求客戶端在發生切換時發送會話ID作為GET或POST請求,這可能會打開Session Fixation的大門。 您可以在切換之前和之后檢查IP地址,有時客戶端的IP地址可以合法地改變,但是切換將是一個非常狹窄的窗口,在這種情況下可以發生這種情況,最重要的是它會完全停止會話固定。

一般來說,你應該避免重新發明風團。 特別是當涉及到這樣已經解決的安全問題時。 如果您需要綁定非http身份驗證,Kerberos非常漂亮。 使用LDAP進行會話管理是另一種可能性。

你真的只是簽署AES密鑰,然后發送加密令牌,密鑰的RSA簽名,然后在PLAINTEXT中發送key-iv?

這是一個失敗。 攻擊者可以使用此密鑰解密令牌,以任何需要的方式更改它並加密回來。 您的服務器永遠不會發現差異。

如果要檢查令牌完整性,只需對其進行哈希並對此哈希進行簽名即可。 這就是哈希所用的。 這里不需要使用加密。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM