x509Chain.build ล้มเหลว certutil - ตรวจสอบผ่าน

ฉันมีใบรับรองหลักและใบไม้ Leaf มีส่วนขยาย CRL URL OID ซึ่งชี้ไปยังตำแหน่งออนไลน์ที่ถูกต้อง ทำสิ่งนี้:

certutil -verify .\leaf.cer

ล้มเหลวด้วย

ข้อผิดพลาด: การตรวจสอบสถานะการเพิกถอนใบรับรอง leaf ที่ส่งคืน ฟังก์ชันการเพิกถอนไม่สามารถตรวจสอบการเพิกถอนได้เนื่องจากเซิร์ฟเวอร์การเพิกถอนอยู่ในสถานะออฟไลน์ 0x80092013 (-2146885613 CRYPT_E_REVOCATION_OFFLINE)

ถ้าฉันทำสิ่งนี้:

certutil -verify .\leaf.cer .\root.cer

จากนั้นการยืนยันก็ผ่าน และฉันเห็นว่า CRL ถูกดึงออกจากออนไลน์ใน Fiddler

ในโค้ด C# ของฉัน ฉันทำสิ่งนี้:

X509Chain childCertChain = new X509Chain();
childCertChain.ChainPolicy.ExtraStore.Add(rootCert);
childCertChain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
childCertChain.ChainPolicy.UrlRetrievalTimeout = TimeSpan.FromSeconds(10);
if (!childCertChain.Build(childCert))
        {
            // The root cert is not in the windows certificate store, that is fine
            if (childCertChain.ChainStatus.Length != 1 || childCertChain.ChainStatus.First().Status != X509ChainStatusFlags.UntrustedRoot)
            {
                throw new Exception("Certificate validation error.");
            }
        }

สิ่งนี้จะเข้าข่ายข้อยกเว้นของฉัน และแม้ว่า chainElements จะถูกเติมด้วยใบรับรอง 2 รายการอย่างถูกต้อง แต่ ChainStatus จะแสดง:

การเพิกถอนแบบออฟไลน์, สถานะการเพิกถอน ไม่ทราบ

ฉันจะไม่เห็นคำขอทางเว็บใด ๆ ใน Fiddler ฉันสามารถดาวน์โหลด CRL โดยทางโปรแกรมโดยใช้ URL ดังนั้นจึงไม่ใช่สภาพแวดล้อมการแก้ไขข้อบกพร่อง AFAIK ของฉัน มีแนวคิดใดบ้างที่จะทำให้ x509Chain.Build ประสบความสำเร็จ?


person serkan    schedule 08.04.2020    source แหล่งที่มา
comment
คุณได้รับองค์ประกอบกี่รายการใน chain.ChainElements   -  person Crypt32    schedule 08.04.2020
comment
มันมี 2 องค์ประกอบ ดังนั้นการสร้างลูกโซ่จึงใช้งานได้ เป็นเพียงส่วนการตรวจสอบเท่านั้นที่ล้มเหลว   -  person serkan    schedule 08.04.2020
comment
จากนั้นผู้ใช้อาจเชื่อถือรูท แต่ไม่ใช่โดยเครื่อง หรือมีปัญหาการตรวจสอบการเพิกถอน   -  person Crypt32    schedule 08.04.2020
comment
ใช่ ในโค้ดด้านบนของฉัน ฉันอนุญาต untrustedRoot แต่ฉันได้รับข้อผิดพลาดอีกสองข้อนี้ใน ChainStatus: OfflineRevocation, RevocationStatusUnknown   -  person serkan    schedule 08.04.2020
comment
certutil -verify -urlfetch cert.cerพูดว่าอะไร ตรวจสอบว่า URL ทั้งหมดใช้งานได้หรือไม่ หรือดีกว่านั้นหลังผลลัพธ์ Certutil   -  person Crypt32    schedule 08.04.2020
comment
ใช่ในคำถามของฉันด้านบนฉันพูดถึงว่า certutil -verify .\leaf.cer ล้มเหลว แต่ certutil -verify .\leaf.cer .\root.cer ผ่าน   -  person serkan    schedule 08.04.2020
comment
ด้วยสวิตช์ -urlfetch?   -  person Crypt32    schedule 08.04.2020
comment
พฤติกรรมเดียวกันกับ -urlfetch ถ้าฉันผ่านทั้งลีฟและรูท มันจะผ่าน ถ้าฉันเพิ่งผ่านลีฟ ฉันเห็น URL ที่ได้รับการยืนยันสำหรับลีฟ แต่มันก็กำลังมองหา URL รูทด้วย แต่ฉันไม่ได้ผ่านใบรับรองรูท ดังนั้นมันจึงล้มเหลว . บางทีสิ่งเดียวกันนี้อาจเกิดขึ้นในรหัสของฉัน บางที extraStore ไม่ได้รับการตรวจสอบเมื่อตรวจสอบความถูกต้องของ URL   -  person serkan    schedule 08.04.2020


คำตอบ (1)


ฉันได้อ่านโค้ดของคุณจากพีซีแล้ว และพบว่าเกิดอะไรขึ้น: ใบรับรองหลักของคุณไม่น่าเชื่อถือในระบบของคุณ Windows CryptoAPI ส่ง CERT_E_UNTRUSTEDROOT เมื่อใบรับรองหลักไม่น่าเชื่อถือ นอกจากนี้ CryptoAPI จะยุติการตรวจสอบการเพิกถอนและส่งข้อผิดพลาดเพิ่มเติมอีกสองรายการ: CRYPT_E_NO_REVOCATION_CHECK และ CERT_E_UNTRUSTEDROOT เนื่องจากการตรวจสอบการเพิกถอนถูกข้ามไป นอกจากรูทที่ไม่น่าเชื่อถือแล้ว CryptoAPI ยังข้ามการตรวจสอบอื่นๆ (เช่น ข้อจำกัด) แต่อย่ารายงานการตรวจสอบเหล่านั้น ทุกอย่างถูกต้องและเป็นไปตามที่คาดไว้

คุณกำลังพยายามอนุญาตการรูทที่ไม่น่าเชื่อถือ แต่ทำไม่ถูกต้อง เพราะวิธีนี้จะทำให้คุณข้ามการตรวจสอบอื่นๆ (ดังที่กล่าวไว้ในย่อหน้าก่อนหน้า) และตรรกะของคุณก็มีความเสี่ยง

คุณสามารถยกเว้นข้อยกเว้นรูทที่ไม่น่าเชื่อถือในการตั้งค่าลูกโซ่ และบังคับให้ CryptoAPI ทำการตรวจสอบต่อไปและส่งคืนความสำเร็จหากไม่พบข้อผิดพลาดอื่นๆ แต่ฉันขอแนะนำอย่างยิ่งว่าอย่าทำเช่นนั้น เพราะคุณจะเปิดรับ MITM ทุกรูปแบบ

คุณมีสองทางเลือก:

  1. ทำให้ใบรับรองหลักที่เชื่อถือได้โดยเครื่อง (ระบบท้องถิ่น) สิ่งนี้อาจเป็นไปไม่ได้
  2. เรียกใช้ฟังก์ชัน CertCreateCertificateChainEngine โดยตรงและใส่ใบรับรองหลักของคุณเป็นสมาชิก hRestrictedTrust ของโครงสร้าง CERT_CHAIN_ENGINE_CONFIG

หากคุณใช้ Windows วิธีที่ 2 จะปลอดภัยและเชื่อถือได้มากที่สุด ณ ขณะนี้ X509Chain ของ .NET ไม่ได้ใช้ฟังก์ชันนี้ ต้องมีการเข้ารหัสเพิ่มเติม แต่ไม่มีทางเลือกอื่นมากนัก

person Crypt32    schedule 08.04.2020
comment
คุณถูกต้อง การติดตั้งใบรับรองช่วยแก้ไขข้อผิดพลาดรูทที่ไม่น่าเชื่อถือ รวมถึงข้อผิดพลาด revocationUnknown ฉันจะพยายามที่จะใช้ 2. หรือได้รับการอนุมัติสำหรับ 1. ขอบคุณ! - person serkan; 09.04.2020
comment
ตัวเลือกที่ 1 เปิดช่องโหว่ด้านความปลอดภัย คุณได้รับคำเตือนแล้ว - person Crypt32; 09.04.2020