0

我有一個Web應用程序,任何人都可以註冊一個帳戶。我想使用客戶端證書進行身份驗證,而不是密碼。這是否實用?在公共Web應用程序中使用客戶端證書代替密碼

好像有很多的問題:

  • 你如何產生一個跨瀏覽器的方式一個密鑰? <keygen>似乎很有用,但我需要支持Internet Explorer。

  • 你如何簽署密鑰對並獲得證書到瀏覽器中?客戶端證書的每一個解釋只包括用於生成證書的openssl命令。我真的不想從我的web應用程序中打開openssl。

  • 由於服務器正在對證書進行簽名,因此如果其簽名(CA)密鑰受到威脅會怎麼樣?這似乎是比密碼數據庫泄漏更嚴重的攻擊,因爲攻擊者可以默默地冒充任何用戶。

    我想避免簽署證書,只使用公鑰指紋作爲用戶的身份。這意味着CA密鑰的知識不能用來冒充任何人,因爲他們沒有用戶的私鑰。

  • 看來以前有人應該做到這一切。整個端到端流程是否有開源的實現? Python或Django實現將特別有用。

這就是我認爲這個過程會是這樣的:

  1. 當用戶註冊後,瀏覽器生成一個密鑰對,併發送一個簽名請求到服務器。
  2. 服務器立即返回一個簽名證書,該證書被加載到瀏覽器中。服務器將密鑰指紋存儲在數據庫中以稍後對用戶進行身份驗證。我不想使用證書DN作爲身份驗證,請參閱上面有關CA妥協的內容。
  3. 前端Web服務器需要客戶端證書,驗證它們,並將公鑰指紋發送到我的應用服務器。
  4. 應用程序服務器通過其密鑰指紋查找用戶,現在進行身份驗證。

我不想處理證書吊銷。由於密鑰指紋用於認證,而不是證書DN數據,因此只需更改與用戶關聯的指紋即可強制使用該密鑰。

編輯:我能夠找到一個實現類似工作流程的演示:https://openweb.or.kr/html5/index_en.php。它在IE中不起作用,並且遇到了我提到的CA問題。

+1

_「這是否實用?」 - 從用戶角度來看:並非如此;如果我想能夠從多個設備訪問您的網絡應用程序,我必須隨身攜帶我的證書。所以我可能會將它存儲到USB設備上,或者在網絡上的某個地方 - 這意味着它實際上已經被暴露了,而不是強大的,但_memorable_密碼會。 (所以除非你的用例是特定的,並且這種情況不太可能 - 我會說不,這是不是最明智的做法。) – CBroe

+0

我忘了提及 - 這個應用程序只能用於單一設備,所以這是一個功能,不是證書不可移植的缺陷。 –

+0

私鑰泄漏在任何使用它們的情況下都是一個問題。這個沒有什麼特別之處。這似乎並不重要,因爲您只使用您已經註冊的指紋,基本上等同於密碼。 – EJP

回答

2

這是否實用?

處理證書對於大多數用戶(包括在IT中工作的人員)具有學習曲線。存儲,移動和保護這些證書可能是一種痛苦。 (前段時間,我在this question on Security.SE上寫了一些關於此主題的內容。)

如何以跨瀏覽器方式生成密鑰對?似乎很有用,但我需要支持Internet Explorer。

你如何簽署密鑰對並獲得證書到瀏覽器中?客戶端證書的每一個解釋只包括用於生成證書的openssl命令。我真的不想從我的web應用程序中打開openssl。

您可能會在this question找到一些有用的指針。特別是,您可以在IE中使用ActiveX生成密鑰對。然後,實現一個服務器端CA.在Java中,BouncyCastle對此非常有用,我想pyOpenSSL在Python中也會很有用。

由於服務器正在對證書進行簽名,如果其簽名(CA)密鑰受到威脅會怎麼樣?這似乎是比密碼數據庫泄漏更嚴重的攻擊,因爲攻擊者可以默默地冒充任何用戶。

確實。

我想避免簽署證書,只使用公鑰指紋作爲用戶的身份。這意味着CA密鑰的知識不能用來冒充任何人,因爲他們沒有用戶的私鑰。

您必須簽署證書才能使其成爲有效的X.509證書,但您可以調整驗證這些證書的各方以忽略簽名並依賴公鑰。客戶端具有與證書的公鑰相匹配的私鑰的事實由TLS握手中的CertificateVerify消息來保證,並且它與驗證證書本身的層相當獨立。

的Apache httpd和在Java都將讓你接受證書,而不必握手過程本身驗證它們(或將讓你自定義如何做到這一點),分別使用SSLVerifyClient optional_no_ca或空TrustManager,但你必須記住執行稍後再進行驗證。特別是,請注意不要將此應用程序與依賴於默認處理程序完成的常規PKI驗證的其他應用程序混合,否則這些應用程序將變得不安全。

存在與此相關的各種問題(特別是哪些認證機構列表將由服務器發送,或者如何選擇客戶端證書)。您可以在this answer中找到關於此的更多詳細信息。

相關問題