C#Webbrowser:以编程方式定义要使用的证书

C#Webbrowser:以编程方式定义要使用的证书,c#,internet-explorer,browser,certificate,programmatically,C#,Internet Explorer,Browser,Certificate,Programmatically,我一直在开发一项服务,该服务连接到一台服务器,该服务器使用数字签名以验证用户身份访问页面。为了能够连接到该网页并使用它,我使用了“WebBrowser”()类 实际上,当到达网页时,会弹出此窗口,选择我电脑中的一个可能证书来识别我自己: 为了解决这个问题,我一直在网上搜索,找到了不同的潜在解决方案,但没有一个能很好地解决这个问题 为了能够解决这个问题,我在类中包含了下一个代码,以便能够捕获来自WebBrowser的函数调用: [Guid("6D5140C1-7436-11CE-8034

我一直在开发一项服务,该服务连接到一台服务器,该服务器使用数字签名以验证用户身份访问页面。为了能够连接到该网页并使用它,我使用了“WebBrowser”()类

实际上,当到达网页时,会弹出此窗口,选择我电脑中的一个可能证书来识别我自己:

为了解决这个问题,我一直在网上搜索,找到了不同的潜在解决方案,但没有一个能很好地解决这个问题

为了能够解决这个问题,我在类中包含了下一个代码,以便能够捕获来自WebBrowser的函数调用:

    [Guid("6D5140C1-7436-11CE-8034-00AA006009FA")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [ComImport]
    public interface UCOMIServiceProvider
    {
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int QueryService(
            [In] ref Guid guidService,
            [In] ref Guid riid,
            [Out] out IntPtr ppvObject);
    }
    [ComImport()]
    [ComVisible(true)]
    [Guid("79eac9d5-bafa-11ce-8c82-00aa004ba90b")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IWindowForBindingUI
    {
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int GetWindow(
            [In] ref Guid rguidReason,
            [In, Out] ref IntPtr phwnd);
    }
    [ComImport()]
    [ComVisible(true)]
    [Guid("79eac9d7-bafa-11ce-8c82-00aa004ba90b")]
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IHttpSecurity
    {
        //derived from IWindowForBindingUI
        [return: MarshalAs(UnmanagedType.I4)]
        [PreserveSig]
        int GetWindow(
            [In] ref Guid rguidReason,
            [In, Out] ref IntPtr phwnd);
        [PreserveSig]
        int OnSecurityProblem(
            [In, MarshalAs(UnmanagedType.U4)] uint dwProblem);
    }
以及一个能够知道何时出现问题并尝试解决问题的函数:

            public int OnSecurityProblem(uint dwProblem)
            {
                int dwCertSelection2 = 2;
                IntPtr dwCertSelection = new IntPtr(dwCertSelection2);
                //ignore errors
                //undocumented return code, does not work on IE6
                if (dwProblem == 12044)
                {

                    X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
                    store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);

                    X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
                    X509Certificate2Collection fcollection = (X509Certificate2Collection)collection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
                    X509Certificate2 x509 = fcollection[2];

                    IntPtr unmanagedPointer = Marshal.AllocHGlobal(x509.RawData.Length);
                    Marshal.Copy(x509.RawData, 0, unmanagedPointer, x509.RawData.Length);

                    bool VF_Resultado = WinHttpSetOption(this.myWebBrowser.Handle, 47, unmanagedPointer, x509.RawData.Length);
                    Marshal.FreeHGlobal(unmanagedPointer);
                    store.Close();
                    return RPC_E_RETRY;
                }

                return S_OK;
            }
要进一步澄清,请执行以下操作:

如果(dwProblem==12044)--->//12044,则需要错误\u INTERNET\u CLIENT\u AUTH\u CERT\u。这表明我们需要通过认证

bool VF_Resultado=WinHttpSetOption(this.myWebBrowser.Handle,47,非托管指针,x509.RawData.Length);-->//INTERNET\u选项\u安全性\u选择\u客户端\u证书47,理论上,通过此功能,我们可以指示我们想要使用的证书,而无需选择它

此代码基于不同的源代码(我尝试了这两种解决方案,但没有成功):

问题是这段代码没有达到预期的效果,我对能否确保它正常工作有各种疑问:

  • 我应该使用WinHTTP、wininet还是其他库
  • 调用函数WinHttpSetOption或InternetSetOption时,句柄应该是什么(函数的第一个参数)
  • 如何传递X509证书以确保WebBrowser理解并使用它?我使用的代码来自C++,我不知道我是否正确地移植了数据,实际上我发送了原始数据。
    谢谢您

    经过多次测试和审查,我得出结论,使用webBrowser控件不可能做到这一点,这是因为必须使用此功能才能通过认证:

    WinHttpSetOption(this.myWebBrowser.Handle, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, dwCertSelection, size)
    
    这里的主要问题是WinHttpSetOption需要在调用函数“HttpOpenRequest”后返回处理程序会话:


    无法从C#WebBrowser对象获取的数据。

    感谢您发布此问题的解决方案。您可以将您的答案标记为已接受的答案。它可以在将来帮助其他社区成员解决类似的问题。谢谢你的理解。