抓取SSL加密的网页(https),含证书验证

因为项目需要,需从向HTTPS页面发送一些数据并获取返回的数据。普通的http网页好办,直接用HttpWebRequest就可以轻松实现。如果对方网页是HTTP但需要登录后才能查看的,也不难实现:用HttpWebRequest加上身份信息构造一个HTTP基层协议内容,再和服务器来一次往返提取到SessionID然后发送就可以搞定。现在的HTTPS+证书是第一次遇到,在中文网上查询到的资料也很少,最后在国外一个网上找到解决办法,写篇文章,方便后来者查看!

以下是代码,不做解释了!

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System;
using System.Net;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Runtime.InteropServices;

/// <summary>
/// Class1 的摘要说明
/// </summary>
public class Class1
{
    private static int CERT_STORE_PROV_SYSTEM = 10;
    private static int CERT_SYSTEM_STORE_CURRENT_USER = (1 << 16);
    ///private static int CERT_SYSTEM_STORE_LOCAL_MACHINE = (2 << 16);

    [DllImport("CRYPT32", EntryPoint = "CertOpenStore", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern IntPtr CertOpenStore(
        int storeProvider, int encodingType,
        int hcryptProv, int flags, string pvPara);

    [DllImport("CRYPT32", EntryPoint = "CertEnumCertificatesInStore", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern IntPtr CertEnumCertificatesInStore(
        IntPtr storeProvider,
        IntPtr prevCertContext);

    [DllImport("CRYPT32", EntryPoint = "CertCloseStore", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern bool CertCloseStore(
        IntPtr storeProvider,
        int flags);

    X509CertificateCollection m_certs;

    public Class1()
    {
        m_certs = new X509CertificateCollection();


        IntPtr storeHandle;
        storeHandle = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, "MY");
        IntPtr currentCertContext;
        currentCertContext = CertEnumCertificatesInStore(storeHandle, (IntPtr)0);
        int i = 0;
        while (currentCertContext != (IntPtr)0)
        {
            m_certs.Insert(i++, new X509Certificate(currentCertContext));
            currentCertContext = CertEnumCertificatesInStore(storeHandle, currentCertContext);
        }
        CertCloseStore(storeHandle, 0);
    }

    public int Init()
    {
        IntPtr storeHandle;
        storeHandle = CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, "MY");
        IntPtr currentCertContext;
        currentCertContext = CertEnumCertificatesInStore(storeHandle, (IntPtr)0);
        int i = 0;
        while (currentCertContext != (IntPtr)0)
        {
            m_certs.Insert(i++, new X509Certificate(currentCertContext));
            currentCertContext = CertEnumCertificatesInStore(storeHandle, currentCertContext);
        }
        CertCloseStore(storeHandle, 0);

        return m_certs.Count;
    }

    public X509Certificate this[int index]
    {
        get
        {
            // Check the index limits.
            if (index < 0 || index > m_certs.Count)
                return null;
            else
                return m_certs[index];
        }
    }
}


---------------------------------------------------------------------------


using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.Text;
using System.Net;
using System.IO;

using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Runtime.InteropServices;

internal class AcceptAllCertificatePolicy : ICertificatePolicy
{
    public AcceptAllCertificatePolicy()
    {
    }

    public bool CheckValidationResult(ServicePoint sPoint, X509Certificate cert, WebRequest wRequest, int certProb)
    {
        return true;
    }
}

public partial class _Default : System.Web.UI.Page
{
    protected static string cookieHeader;

    protected void Page_Load(object sender, EventArgs e)
    {
    }


    protected void btnSend_Click(object sender, EventArgs e)
    {

        ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();


        string postData = @"CREDITID=CDB992362323";
        Encoding encoding = Encoding.GetEncoding("gb2312");
        string strUrl = https://www.server.com/asdfjlsdf.jsp;
        byte[] data = encoding.GetBytes(postData);
        //准备请求...  
        HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(strUrl);
        myRequest.ClientCertificates.Add(s[0]); //证书可以遍历出来让客户选择,但我这里是测试程序,直接就选择我需要的那个了。
        myRequest.Method = "POST";
        myRequest.ContentType = "application/x-www-form-urlencoded";
        myRequest.ContentLength = data.Length;
        myRequest.KeepAlive = true;

        Stream newStream = myRequest.GetRequestStream();
        //发送数据  
        newStream.Write(data, 0, data.Length);
        newStream.Close();

        //读取回来的数据
        HttpWebResponse res = (HttpWebResponse)myRequest.GetResponse();
        StreamReader sr = new StreamReader(res.GetResponseStream(), System.Text.Encoding.Default);
        txtAccept.Text = sr.ReadToEnd();
        sr.Close();
        res.Close();  

        return;
       }
}

posted @ 2008-07-12 00:06  冰封的心  阅读(1358)  评论(2编辑  收藏  举报