在Windows平台上,实现SSL的.NET类是System.Net.Security.SslStream类。这个类既可以用于建立SSL服务,也可以用来作为SSL客户端连接远端的SSL服务。

最简单的SSL客户端是连接一个无需客户端验证的服务器,客户端不必出示数字证书。对公众提供服务的门户网站的https入口一般都是如此,检验服 务器证书的有效性是客户端自己的事情。浏览器自己是一个典型的SSL客户端,由于客户端要负责验证服务器证书,所以使用可信的浏览器对于安全上网十分重 要。SSL服务器端网上很好找,随便选一个https网站作为对端,我们的客户端演示程序就能够建立一个实际的SSL安全连接了。

这里,我们的客户端程序连接一个拥有公网数字证书的https网站,如https: //www.alipay.com。默认的系统安全配置会检验服务器给出的证书,决定安全协商的结果。如果远端数字证书有 效,SslStream.AuthenticateAsClient函数调用会成功,不抛出任何异常。这个函数的名称不是很准确,看起来像是只做了鉴别工 作,实际上这个函数如果正常完成,意味着整个SSL握手工作的完成,包括鉴别和密钥交换。应用程序随后就可以用这个SslStream对象的读写函数与远 端服务器安全通信,如请求一个网页等等,服务器发送账单,用户提交用户信用卡号等敏感信息都应该在这样的安全连接中进行。

这里我们先建立一个普通的TCP连接,然后在基于这个TCP连接的通信通道,建立SSL安全连接。这里我们不讨论普通TCP连接的建立和使用问题。

我们的例子代码的功能是,作为ssl客户端,连接一个知名的网站的https服务的端口。这个端口一般是443。ssl握手鉴别成功之后,我们在 ssl通道上给服务器发送一个http页面请求,然后接收服务器应答的html页面数据,把页面源码直接以字符形式打印在控制台上。感兴趣的读者可以进一 步把它保存成html文件,用浏览器打开查看返回的网页。

代码的简要流程如下:

1 建立普通tcp连接。

2 构造sslstream对象

3 在try块中,调用authenticateasclient开始ssl握手过程,试图与也服务器建立ssl连接。

4 安全地 收发加密的数据,或者 在catch块中处理ssl握手异常。

代码全文如下:

using System;
using System.Collections;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Text;
using System.Security.Cryptography.X509Certificates;
using System.IO; namespace Examples.System.Net
{
public class SslTcpClient
{
private static Hashtable certificateErrors = new Hashtable(); // 验证服务器证书的回调函数。
public static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{ if (sslPolicyErrors == SslPolicyErrors.None)
return true; Console.WriteLine("Certificate error: {0}", sslPolicyErrors); // 不能通过的服务器证书验证的,返回false,阻止建立连接。
return false; }
public static void RunClient(string machineName, string serverName)
{
// 1 建立普通tcp连接。
TcpClient client = new TcpClient(machineName, 443);
Console.WriteLine("Client connected.");
// 2 构造SslStream类的对象.
SslStream sslStream = new SslStream(
client.GetStream(),
false,
new RemoteCertificateValidationCallback(ValidateServerCertificate),
null
);
// The server name must match the name on the server certificate.
try
{
// 3 发起ssl握手,试图建立ssl连接.
                sslStream.AuthenticateAsClient(serverName, null, SslProtocols.Tls, false);
}
catch (AuthenticationException e)
{
Console.WriteLine("Exception: {0}", e.Message);
if (e.InnerException != null)
{
Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
}
Console.WriteLine("Authentication failed - closing the connection.");
client.Close();
return;
}
// Encode a test message into a byte array.
// Signal the end of the message using the "<EOF>".
byte[] messsage = Encoding.UTF8.GetBytes("GET " + machineName + "/ HTTP/1.0\r\n");
// 发送ssl加密数据。.
sslStream.Write(messsage);
sslStream.Flush();
// Read message from the server.
string serverMessage = ReadMessage(sslStream);
Console.WriteLine("Server says: {0}", serverMessage);
// Close the client connection.
client.Close();
Console.WriteLine("Client closed.");
}
static string ReadMessage(SslStream sslStream)
{
// Read the message sent by the server.
// The end of the message is signaled using the
// "<EOF>" marker.
byte[] buffer = new byte[2048];
StringBuilder messageData = new StringBuilder();
int bytes = -1;
do
{
//接收来自服务器的Ssl加密保护的数据。
                bytes = sslStream.Read(buffer, 0, buffer.Length);

                // Use Decoder class to convert from bytes to UTF8
// in case a character spans two buffers.
Decoder decoder = Encoding.UTF8.GetDecoder();
char[] chars = new char[decoder.GetCharCount(buffer, 0, bytes)];
decoder.GetChars(buffer, 0, bytes, chars, 0);
messageData.Append(chars);
} while (bytes != 0); return messageData.ToString();
}
private static void DisplayUsage()
{
Console.WriteLine("To start the client specify:");
Console.WriteLine("clientSync machineName [serverName]");
Environment.Exit(1);
}
public static int Main(string[] args)
{
string serverCertificateName = "www.taobao.com";
string machineName = "www.taobao.com";
SslTcpClient.RunClient(machineName, serverCertificateName);
return 0;
}
}
}

在调试器中,看到的sslStream对象的状态如下:

代码运行的结果如下:

我们看到了服务器通过SSL安全通道返回的HTML网页数据。

SSL编程(2).NET最简单的客户端的更多相关文章

  1. 利用openssl管理证书及SSL编程第1部分: openssl证书管理

    利用openssl管理证书及SSL编程第1部分 参考:1) 利用openssl创建一个简单的CAhttp://www.cppblog.com/flyonok/archive/2010/10/30/13 ...

  2. SSL编程(3).NET实现SSL服务端

      准备开发用数字证书 一般学习和开发调试场合,不会随便使用正式的SSL服务器证书的私钥.由于服务器验证对于SSL来说是必须的,SSL服务器端必须有拥有一个服务器 证书,即能够访问到证书的私钥.对于要 ...

  3. Netty学习——基于netty实现简单的客户端聊天小程序

    Netty学习——基于netty实现简单的客户端聊天小程序 效果图,聊天程序展示 (TCP编程实现) 后端代码: package com.dawa.netty.chatexample; import ...

  4. 【Hadoop离线基础总结】zookeeper的介绍以及集群环境搭建、网络编程和RPC的简单了解

    ZooKeeper的介绍以及集群环境搭建.网络编程和RPC的简单了解 ZooKeeper介绍 概述 ZooKeeper是一个分布式协调服务的开源框架,主要用来解决分布式集群中应用系统的一致性问题.例如 ...

  5. Arduino下LCD1602综合探究(上)——1602的两种驱动方式,如何使LCD的控制编程变得更简单

    一.前言: LCD ( Liquid Crystal Display 的简称)液晶显示器,已经逐渐替代CRT成为主流的显示设备之一,因此也成为了单片机发烧友绕不过的话题之一:而LCD1602更是很多单 ...

  6. android 学习随笔九(网络:简单新闻客户端实现)

    1.简单新闻客户端 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xm ...

  7. 利用JSP编程技术实现一个简单的购物车程序

    实验二   JSP编程 一.实验目的1. 掌握JSP指令的使用方法:2. 掌握JSP动作的使用方法:3. 掌握JSP内置对象的使用方法:4. 掌握JavaBean的编程技术及使用方法:5. 掌握JSP ...

  8. 利用openssl管理证书及SSL编程第2部分:在Windows上编译 openssl

    利用openssl管理证书及SSL编程第2部分:在Windows上编译 openssl 首先mingw的环境搭建,务必遵循下文: http://blog.csdn.net/ubuntu64fan/ar ...

  9. shell编程其实真的很简单(一)

    如今,不会Linux的程序员都不意思说自己是程序员,而不会shell编程就不能说自己会Linux.说起来似乎shell编程很屌啊,然而不用担心,其实shell编程真的很简单. 背景 什么是shell编 ...

  10. Java新AIO/NIO2:AsynchronousServerSocketChannel和AsynchronousSocketChannel简单服务器-客户端

    Java新AIO/NIO2:AsynchronousServerSocketChannel和AsynchronousSocketChannel简单服务器-客户端用AsynchronousServerS ...

随机推荐

  1. codeforces966 A

    这题主要就是考虑y1两侧的最近的电梯和楼梯 当时主要是考虑  如果电梯在y1和y2中间的话   那么直接做电梯就是最优解   如果在y2右边就用abs去算 然后发现其实只考虑 y1的左右两边的电梯和楼 ...

  2. HDU 2476 区间DP-刷字符问题-思维考察

    区间DP-刷字符问题-思维考察 翻译了一下这个题,一看还是有点难以入手,标明了是区间DP问题,但是如何DP呢 来捋一捋思路吧 dp[i][j]肯定是从i刷到j所要的次数但是它的i和j是s1串还是s2串 ...

  3. bootstrap1.3

    <html>   <head>   <meta charset="UTF-8">   <title></title>   ...

  4. phpstudy 配置 memcached / memcache

    https://blog.csdn.net/zql898626913/article/details/77309269

  5. ReportMachine OCX 的使用方法

    ReportMachine OCX http://rmachine.haotui.com/thread-55-1-1.html RMReport.ocx RMEngine.Init(1); // 初始 ...

  6. 房屋贷款计算器 Mortgage Calculator

    闲暇时间开发了一款工具 - 房屋贷款计算器 Mortgage Calculator 有需要的可以下载来试试. JACK NJ @ 2017

  7. Html Agility Pack解析Html(C#爬虫利器)

    有个需求要写网络爬虫,以前接触过一个叫Html Agility Pack这个解析html的库,这次又要用到,然而发现以前咋用的已经不记得了,现在从头开始记录一下使用过程. Html Agility P ...

  8. sharepoint support ashx file

    Hello, I did the steps from the tutorial you are using. I have received the same error when I did no ...

  9. 识别同音字词pypinyin, 分词 jieba

    一.pypinyin 在处理语音输入指令时, 比如 请给圆圆发消息,那么转化为文字识别时, 无法确定转换的是圆圆还是园园或是源源, 为了解决这个问题, 就把指令转换为拼音来处理,这样就可以处理同音字了 ...

  10. Linux正则与文本处理工具(10)

    正则表达式 (Regular Expression, RE, 或称为常规表达式)是通过一些特殊字符的排列,用于『查找/替换/删除』一行或多行文字或字符串,简单的说,正则表达式就是用在字串的处理上面的一 ...