當客戶端根本沒有設定 SNI 服務器名時,Java 如何選擇默認/備用服務器證書?
背景:
我創建了具有多個服務器證書的 PKCS#12 密鑰庫。我也用 JKS 密鑰庫進行了測驗。我使用NewSunX509的實作X509KeyManager可以根據請求的 SNI 服務器名選擇匹配的服務器證書。
我找不到 JSSE 用來選擇默認或“回退”服務器證書的規則,當客戶端未在 TLS 握手中發送 SNI 服務器名時,它會回傳該證書。我沒有找到檔案或通過測驗弄清楚。實作(代碼鏈接)說它對不完美的匹配進行排序。在實踐中,選擇似乎受到在密鑰庫中添加條目的順序的影響,但它并不是簡單地選擇第一個或最后一個條目,或者按別名排序,即使代碼注釋給出了這種印象。
uj5u.com熱心網友回復:
我沒有看到任何關于按別名排序的評論。如果發生不完全匹配排序,它EntryStatus.compareTo首先使用哪個排序CheckResult(即衡量證書與“好”的接近程度),然后keyIndex是它在keyTypes呼叫者基于 SSL/TLS 協議的請求串列中的位置(即 ciphersuite(s) 和/或 signature_algorithm 值,可能按優先順序排列)。如果它們都相等,Collections.sort那么它是穩定的,因此它將使用它們被測驗和發現的順序,請參閱下一個。
然而,排序只有在沒有“完美”匹配的情況下才會發生;一旦找到任何“完美”匹配,它就會回傳而不尋找任何可能存在的其他匹配。因此,回傳哪個取決于查看和測驗密鑰庫條目的順序。chooseAlias正如您所鏈接的,以及它的 with-SNI-idalg 兄弟,如果有多個,則首先按“構建器”順序查看,通常不會有;并且在他們呼叫的“構建器”中(即在密鑰庫中)getAliases,您可以看到使用Enumeration回傳的ks.aliases()- 這由KeyStore使用的實體確定。
像 PKCS12 和 JKS 這樣的基于檔案的Map密鑰庫通常使用一個或舊的(pre-Collection)Hashtable以別名作為密鑰。特別是 PKCS12 使用LinkedHashMap它按插入的順序回傳密鑰/條目,我認為這或多或少是它們在存盤檔案中存在的順序(盡管在 PKCS12 中,證書和私鑰的順序可能不同,我不確定哪些控制元件)但是這不需要與別名/名稱、創建或其他任何東西的順序相同。JKS 使用Hashtable它以哈希碼的降序對映射大小取模,映射大小主要取決于插入的條目數,并且在發生沖突的情況下,它使用鏈表并以插入的相反順序回傳——除非可能重新散列改變了這一點。
對于像 PKCS11、Windows、Apple 這樣的非基于檔案的密鑰庫,它可以由 Java 介面代碼、底層設施提供的內容或組合來確定。
TLDR:就您而言,它是不可預測的,出于實際目的,它也可能是隨機的。如果你關心你得到哪一個,要么撰寫你自己的KeyManager邏輯來實作你的選擇(或使用像 Apache httpcomponents 這樣的預先撰寫的邏輯),要么過濾你提供給默認 KeyManager 的密鑰庫中的資料。
另外要明確的是,這僅適用NewSunX509于您指定的情況。默認的KeyManager 是(仍然!)較舊的SunX509并且作業方式不同;它有自己的HashMap 來控制迭代,而不是使用底層密鑰庫的。(單數,因為 SunX509 只需要一個。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/485656.html
上一篇:在Powershell中運行wixExeCommand時出錯:無法識別術語“::SecurityProtocol”
下一篇:尤里卡服務器ssl配置
