20

X509Certificate (または X509Certificate2) に「Extended Validation」(EV) フラグが設定されているかどうかを C# (.Net 4.0) アプリケーションから確認する信頼できる方法を見つけるのに苦労しています。誰もが最良の方法を知っていますか?

4

2 に答える 2

23

X509CertificateにこれらのOIdのいずれかが含まれているかどうかを確認できます。さらに、実装されているOIdのリストについて、Chromiumのソースを確認できます。ソースはここにあります。Firefoxに固執したい場合は、ここで実装を入手できます。

ソースを更新してテストしました。X509Certificate2Wikipedia/ChromiumのOIdリストに対してを検証するための小さなメソッドを作成しました。この方法では、Wikipedia-Listを使用していますが、代わりにChromium-Listを使用する方がよい場合があります。


OIdはどのように保存されますか?

それぞれCAに1つ以上OIdのObjectIdがあります。ご想像のとおり、これらは拡張機能として保存されません。ポリシー拡張機能内のエントリとして保存されますPolicy Extension正確な拡張子を取得するには、フレンドリ名を使用するのではなく、それ自体のOidを使用することをお勧めします。ポリシー拡張のOIDはです2.5.29.32

情報の抽出

ポリシー拡張機能の内部コンテンツを取得するためSystem.Security.Cryptography.AsnEncodedDataに、それを読み取り可能なものに変換するために使用できますstringstring[]文字列自体には、のOIdの1つが含まれているかどうかを確認するために照合する必要のあるポリシーが含まれていますEV Certificate

ソース

    /// <summary>
    /// Checks if a X509Certificate2 contains Oids for EV
    /// </summary>
    /// <param name="certificate"></param>
    /// <returns></returns>
    private static bool IsCertificateEV(X509Certificate2 certificate)
    {
        // List of valid EV Oids
        // You can find correct values here:
        // http://code.google.com/searchframe#OAMlx_jo-ck/src/net/base/ev_root_ca_metadata.cc&exact_package=chromium
        // or in Wikipedia
        string[] extendedValidationOids = 
        {
            "1.3.6.1.4.1.34697.2.1",
            "1.3.6.1.4.1.34697.2.2",
            "1.3.6.1.4.1.34697.2.1", 
            "1.3.6.1.4.1.34697.2.3", 
            "1.3.6.1.4.1.34697.2.4",
            "1.2.40.0.17.1.22",
            "2.16.578.1.26.1.3.3",
            "1.3.6.1.4.1.17326.10.14.2.1.2", 
            "1.3.6.1.4.1.17326.10.8.12.1.2",
            "1.3.6.1.4.1.6449.1.2.1.5.1",
            "2.16.840.1.114412.2.1",
            "2.16.528.1.1001.1.1.1.12.6.1.1.1",
            "2.16.840.1.114028.10.1.2",
            "1.3.6.1.4.1.14370.1.6",
            "1.3.6.1.4.1.4146.1.1",
            "2.16.840.1.114413.1.7.23.3",
            "1.3.6.1.4.1.14777.6.1.1", 
            "1.3.6.1.4.1.14777.6.1.2",
            "1.3.6.1.4.1.22234.2.5.2.3.1",
            "1.3.6.1.4.1.782.1.2.1.8.1",
            "1.3.6.1.4.1.8024.0.2.100.1.2",
            "1.2.392.200091.100.721.1",
            "2.16.840.1.114414.1.7.23.3",
            "1.3.6.1.4.1.23223.2", 
            "1.3.6.1.4.1.23223.1.1.1", 
            "1.3.6.1.5.5.7.1.1",
            "2.16.756.1.89.1.2.1.1",
            "2.16.840.1.113733.1.7.48.1",
            "2.16.840.1.114404.1.1.2.4.1",
            "2.16.840.1.113733.1.7.23.6",
            "1.3.6.1.4.1.6334.1.100.1",
        };

        // Logic:
        // Locate Certificate Policy Extension
        // Convert to AsnEncodedData (String)
        // Check if any of the EV Oids exist
        return (
                from X509Extension ext in certificate.Extensions 
                where ext.Oid.Value == "2.5.29.32" 
                select new AsnEncodedData(ext.Oid, ext.RawData).Format(true))
                .Any(asnConvertedData => extendedValidationOids.Where(asnConvertedData.Contains).Any()
            );
    }

開始するためにいくつかのソースが必要な場合:

    static void Main(string[] args)
    {
        // Create Delegate for analysis of X509Certificate
        ServicePointManager.ServerCertificateValidationCallback = ValidateServerCertificate;

        // Make sample request to EV-Website to get Certificate
        var wc = new WebClient();
        wc.DownloadString("https://startssl.com");  // EV
        wc.DownloadString("https://petrasch.biz");  // Not EV
        Console.ReadLine();
    }

    public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        var cert = (X509Certificate2) certificate;
        Console.WriteLine("Certificate: " + cert.GetNameInfo(X509NameType.SimpleName, true) + " -> " + IsCertificateEV(cert));
        return true;
    }

誰かがこの目標を達成するためのより良い方法を知っているなら、私たちに知らせてください。

于 2013-02-05T10:27:25.360 に答える