当前位置:编程学习 > C#/ASP.NET >>

抓取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;

       }

}

 

--------------------编程问答-------------------- 帮顶。 --------------------编程问答-------------------- 有没有用C++实现的啊,这个看起来不太懂。 --------------------编程问答-------------------- 哪里用得着那么麻烦啊,用.NET内置的证书操作类就完全可以实现了,很简单,外加你代码格式太糟糕了,不用代码格式化标签,谁高兴看啊。 --------------------编程问答-------------------- 感谢分享,先标记一下,再去试试。能提供下原网址么?

我最近需要用到,之前用到的一个方法不成功。

WebClient DownFile = new WebClient();
CredentialCache mycache = new CredentialCache();
mycache.Add(new Uri(域名), 证书名, new NetworkCredential(用户名, 密码));
DownFile.Credentials = mycache;
DownFile.DownloadFile(附件网址, 本地文件名);


另,#3有什么简便的方法,可以说详细一些么?发个相关的链接也同样感谢! --------------------编程问答-------------------- 刚看了一下代码,其中的postData,里面是用户名么?
我这里的证书后缀是P12,浏览器进入的时候还要输用户名密码。
恳请哪位大侠告知这样的证书该如何操作?
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,