金沙棋牌app手机下载

当前位置:金沙棋牌 > 金沙棋牌app手机下载 > 深入理解HTTPS协议,MsSQL使用加密连接SSL

深入理解HTTPS协议,MsSQL使用加密连接SSL

来源:http://www.logblo.com 作者:金沙棋牌 时间:2019-09-13 06:26

说明

应用程序通过未加密的通道与数据库服务器通信, 这可能会造成重大的安全风险。在这种情况下, 攻击者可以修改用户输入的数据, 甚至对数据库服务器执行任意 SQL 命令。

例如,当您使用以下连接字符串时,就可能存在这种风险:

<connectionStrings>  
<add name="Test" connectionString="Data Source=210.10.20.10,1433; Initial Catalog=myDataBase;User ID=myUsername;Password=myPassword;" providerName="System.Data.SqlClient" /> 
</connectionStrings>

 

!!!
!!! 你们这些旱鸭子比我想象得要厉害多了,看来我要认真一些了 !!!

金沙棋牌app手机下载 1

重拳先生

HTTS协议实际就是标准的HTTP协议加上SSL/TLS层.它能防止我们的信息被窃取,暴露出不安全.或者进入钓鱼网址.通过下面这个讲解,我希望能明白SSL/TLS层到底为我们做了哪些事情,才能保证我们的信息安全.

概述


TLS是现在广泛使用的安全协议,全名为传输层安全协议(Transport Layer Security).它的前身是SSL,即安全套接层(Secure Socket Layer).

网景公司(Netscape)在1994年推出首版网页浏览器,网景导航者时,推出HTTPS协议,以SSL进行加密,这是SSL的起源。

后来,Google在04年发布 在SSL 3.0中发现设计缺陷,建议禁用此一协议。攻击者可以向TLS发送虚假错误提示,然后将安全连接强行降级到过时且不安全的SSL 3.0,然后就可以利用其中的设计漏洞窃取敏感信息。最后各大公司都选择了强制使用TLS.

目前SSL/TLS已成为互联网上保密通讯的工业标准

更新: 这个SSL/TLS就像是在应用层和传输层中间多加的半层. 其实就是库嘛, 应用程序可以选择性的进行调用. 以Web服务为例, 如果没有调用的话就是http, 如果调用了的话就是https了.反正提供了API. 二者虽然只有一个字的差距但是却又很大的不同的. 一个是文本格式的, 一个是二进制的格式的.

尽管他自己是半个层, 但是其内部也是分了很多层的(进行了分层设计), 简单的说一下:

  1. 最底层: 基础算法原语的实现, aes, rsa, md5
  2. 向上一层: 各种算法的实现
  3. 再向上一层: 组合算法实现的半成品
  4. 用各种组件拼装而成的种种成品密码学协议/软件:
    1. tls, ssh, ...

启用SSL/TLS加密连接

大部分数据库服务器都提供支持使用SSL/TLS来加密传输所有数据,您应当尽可能的使用它。在您的连接字符串上加上Encrypt=True即可。如果您的开发环境没有可信证书,加上TrustServerCertificate=True来取消验证证书是否受信。

<connectionStrings>  
<add name="Test" connectionString="Data Source=210.10.20.10,1433; Initial Catalog=myDataBase;User ID=myUsername;Password=myPassword;Encrypt=True;" providerName="System.Data.SqlClient" /> 
</connectionStrings>

 

相关链接:

原文链接:

现在来聊聊服务器的加密,这文章会覆盖整个 Node.js 加密的前因后果,所以会比较长,内容分为:

1. HTTPS到底做了哪些事情

HTTPS采用众所周知和理解的HTTP协议,并简单地将SSL / TLS加密层层叠在其上。服务器和客户端仍然使用相同的HTTP,但通过安全的SSL连接来加密和解密他们的请求和响应。 SSL层有两个主要目的:

  • 保证你是在跟真正的服务器通信,而不是伪装的服务器.
  • 保证只有真正的服务器才能解密你发送的信息.同时,也只有你才能解密服务器跟你发送消息.就是保证是你跟真正的服务器在通信,这过程中没有第三者.

在这过程中,其他人还是可以中途截取到你发送的信息,但是是加密的,它们拿到也无法解密.

正片开始


提到了TLS,就一定要说一下HTTPS了,一般对HTTPS的定义是HTTP over SSL/HTTP over TLS/HTTP over Secure.

而提到了HTTPS,有不得不说一下浏览器了.那么我来慢慢按照顺序来说一下.

首先,HTTPS借由HTTP(如果对HTTP不熟悉可以考虑看一下隔壁的HTTP阅读笔记)来传输信息,但为了某些需要,要加密某些信息,此时它就借助了SSL/TLS来加密传输的数据包.一般的,HTTPS的默认使用端口为443.

最重要的部分就是协议实现的方式了.
下面来说下:(可以结合下面的图来看,超清版的.SVG)


首先客户端向Web服务器发送一个HTTPS请求,该请求包含了客户端的条件以及一个随机数.关键字:{ 本地条件 }

  • 具体内容包括:支持的协议版本,比如TLS1.0版,一个客户端生成的随机数(稍后用于生成“会话密钥”),支持的加密算法(如RSA公钥加密)和支持的压缩算法。

此时,客户端的随机数被Server端获得.

然后收到一个Server回应消息,这个回应中确定了双方在后来要使用的各种连接参数.关键字:{ 确定参数 }

  • 这次的回应包括:确认使用的加密通信协议版本,比如TLS 1.2版本(如果浏览器与服务器支持的版本不一致,服务器关闭加密通信),一个服务器生成的随机数(稍后用于生成“对话密钥”),确认使用的加密方法(如RSA公钥加密),服务器证书。

此时,双方手中都有了双方的随机数.
至此,Phase 1结束.

  • { Phase1中交换了随机数,确定了连接参数 }

再然后当双方知道了连接参数,客户端与服务器交换证书(依靠被选择的公钥系统)(Phase2-Phase3)

服务器端向客户端发送自己的证书和公钥并要求客户端提供证书. 看到这里,想必会有这样的疑问:客户端哪里来的证书?

我认为,本机的电子证书是通过浏览器中预设的CA来获取的.

SSL 服务器证书提供加密和安全功能。
客户端证书提供用户身份验证功能。
客户端证书由证书颁发机构颁发给用户。

客户端这边,通过CA的公钥解密服务器端的证书,还会检测是否被吊销, 确认是否有效.

  • 所以说,这里的证书是经过了认证中心的私钥加密的

关键字:{ 确认服务器端身份 }

此时,客户端手中多了服务器端的公钥.
至此,Phase2结束.

  • {Phase2中客户端验证了服务器的身份}

接着根据之前的请求,客户端向服务器端发送自己的证书和自己的公钥.

客户端有证书即双向身份认证,没证书时随机生成公钥。

服务器端对客户端发来的证书进行检查,如果有问题会直接中断私密通信.

然后,客户端再次生成一个随机数,注意,此时生成的随机数是经过了服务器端公钥的加密的,接着将其发送到了服务器端.

当服务器端收到了这个随机数,(我们把他叫做pre-master-secret),双方会根据之前商定的加密方法,对之前的两个随机数加上这个PMS,生成一个会话密钥(MS).

此时,服务器端手中自己的公钥和私钥,以及MS
金沙棋牌app手机下载,客户端手中有自己的公钥和私钥,以及MS
至此,Phase3结束.

  • {Phase3中双方得到了会话密钥}

最后,双方关键数据的加密传输均使用这个“会话密钥”--主密钥

结束SSL握手.

至此,全部的SSL握手结束.

金沙棋牌app手机下载 2

SSL

  • <a>从 OpenSSL 开始</a>
  • <a>TLS HTTPS 服务器</a>
  • <a>Crypto 加密解密</a>
2. SSL/TLS是如何建立连接的

客户端和服务器端通过握手来建立连接的,目的有以下3点。

  • 保证客户端正在和正确的服务器通信
  • 有关各方已就“密码套件”达成一致,该密码套件包括将用于交换数据的加密算法
  • 对密匙达成一致,双方使用相同的密匙

一旦建立连接,双方就可以使用商定的算法和密钥将消息安全地发送给对方。我们将握手分为三个主要阶段

  • Hello,证书交换和密钥交换。
  1. Hello - 握手从客户端发送ClientHello消息开始。这包含服务器通过SSL/TLS连接到客户端所需的所有信息,包括它支持的各种密码套件和最大SSL/TLS版本。服务器响应ServerHello,其中包含客户端所需的类似信息,包括基于客户端有关哪个密码套件和SSL/TLS版本将被使用的偏好的决定。
  2. 证书交换 - 现在联系已建立,服务器必须向客户证明其身份。这是通过使用SSL证书来实现的,该证书与其护照非常相似。 SSL证书包含各种数据,包括所有者的名称,所连接的属性,证书的公钥,数字签名以及有关证书有效日期的信息。客户端检查它是隐式信任证书,还是验证它是否被其隐含信任的几个证书颁发机构之一验证和信任。请注意,服务器也可以要求证书来证明客户的身份,但这通常只发生在非常敏感的应用程序中。
  3. 密钥交换 - 客户端和服务器交换的实际消息数据的加密将使用对称加密算法完成,其确切性质在Hello阶段已经达成一致。对称算法使用单个密钥进行加密和解密,与需要公钥/私钥对的非对称算法相反。双方需要就这个单一的对称密钥达成一致,这个安全使用非对称加密和服务器的公钥/私钥完成的过程。客户端先用非对称加密算法的公钥把通信过程中需要的私钥传给服务端,服务端用私钥解读出以后通信过程中的私钥。

客户端生成一个用于对称加密算法的随机密钥。它使用在Hello阶段同意的算法和服务器的公钥(在其SSL证书上找到)对其进行加密。它将这个加密的密钥发送到服务器,在那里使用服务器的私钥解密,并且握手的有趣部分已完成。双方都非常高兴,他们正在与正确的人交谈,并秘密地同意了一个密钥,以对称加密的方式加密他们将要发送的数据。 HTTP请求和响应现在可以通过形成明文消息然后加密并发送来发送。另一方是唯一知道如何解密此消息的人,因此中间人攻击者无法读取或修改他们可能拦截的任何请求。

金沙棋牌app手机下载 3image.png

SSL/TLS的延时问题


既然HTTPS的数据传递是相对安全的,那为什么不给每一个域名都配上HTTPS呢?

原因很简单,延时,因为复杂的握手机制,会使得访问时间延长很多,那么到底有多少呢?

首先,HTTPS是建立在HTTP的,HTTP又是建立在TCP/IP上的,因此必定存在三次握手.

所以,我们可以得到:

HTTP耗时 = TCP握手
HTTPs耗时 = TCP握手 + SSL握手

我们可以做一个小测试:

命令行工具curl有一个w参数,可以用来测量TCP握手和SSL握手的具体耗时,以访问支付宝为例。

$ curl -w "TCP handshake: %{time_connect}, SSL handshake: %{time_appconnect}n" -so /dev/null https://www.alipay.com

我测试的一些结果样本供参考:

TCP handshake: 0.053, SSL handshake: 0.129
TCP handshake: 0.079, SSL handshake: 0.187
TCP handshake: 0.075, SSL handshake: 0.145
TCP handshake: 0.077, SSL handshake: 0.150

从结果可以看到,SSL握手的耗时大概是TCP握手的二-三倍。

也就是说,在建立连接的阶段,HTTPs链接比HTTP链接要长2-3倍的时间,当然了,具体数字取决于CPU的快慢和网络状况。

在此之前呢,先回答一下混乱的问题。

3. 证书

对于请求方来说,它怎么能确定它所得到的公钥一定是从目标主机那里发布的,而且没有被篡改过呢?亦或者请求的目标主机本本身就从事窃取用户信息的不正当行为呢?这时候,我们需要有一个权威的值得信赖的第三方机构(一般是由政府审核并授权的机构)来统一对外发放主机机构的公钥,只要请求方这种机构获取公钥,就避免了上述问题的发生。用户首先产生自己的密钥对,并将公共密钥及部分个人身份信息传送给认证中心。认证中心在核实身份后,将执行一些必要的步骤,以确信请求确实由用户发送而来,然后,认证中心将发给用户一个数字证书,该证书内包含用户的个人信息和他的公钥信息,同时还附有认证中心的签名信息。用户就可以使用自己的数字证书进行相关的各种活动。数字证书由独立的证书发行机构发布,数字证书各不相同,每种证书可提供不同级别的可信度。证书的验证是通过验证证书的数字签名(CA的公钥来解开签名,并与原文hash之后的摘要做对比).

最后,再来说说session恢复的问题


如果出于某种原因,对话中断,就需要重新握手。

之前说过,SSL是很要时间的,因此,要想出一种办法来快速恢复.

这时有两种方法可以恢复原来的session:一种叫做session ID,另一种叫做session ticket

session ID的思想很简单,就是每一次对话都有一个编号(session ID)。如果对话中断,下次重连的时候,只要客户端给出这个编号,且服务器有这个编号的记录,双方就可以重新使用已有的"对话密钥",而不必重新生成一把。

[图片上传失败...(image-cccd4b-1523105936228)]

上图中,客户端给出session ID,服务器确认该编号存在,双方就不再进行握手阶段剩余的步骤,而直接用已有的对话密钥进行加密通信。

但是,sessionID是存储在一个服务器上的,一旦有发向另一台的请求,就又会重新开始了.

为了解决这个问题,session ticket应运而生.

[图片上传失败...(image-68ef83-1523105936228)]

上图中,客户端不再发送session ID,而是发送一个服务器在上一次对话中发送过来的session ticket。这个session ticket是加密的,只有服务器才能解密,其中包括本次对话的主要信息,比如对话密钥和加密方法。当服务器收到session ticket以后,解密后就不必重新生成对话密钥了。

什么是 SSL ?

Secure Sockets Layer,这是其全名,他的作用是协议,定义了用来对网络发出的数据进行加密的格式和规则。

      +------+                                            +------+
服务器 | data | -- SSL 加密 --> 发送 --> 接收 -- SSL 解密 -- | data | 客户端 
      +------+                                            +------+   

      +------+                                            +------+
服务器 | data | -- SSL 解密 --> 接收 <-- 发送 -- SSL 加密 -- | data | 客户端 
      +------+                                            +------+   

1994年,Mozilla 前身 NetScape 公司制定出 1.0 版本。
1995年,NetScape 正式发布 SSL,版本是 2.0。
1996年,NetScape 发布 3.0,获得广泛应用。
1999年,ISOC 接管 SSL,制定世界标准同时升级 SSL 版本,改称 TLS,版本 1.0。
2001年,ISOC 的较新版本 TLS 1.2。

注:TLS 1.0 等同于 SSL 3.1,TLS 1.1 等同于 SSL 3.2,TLS 1.2 等同于 SSL 3.3。

4. 数字签名

数字签名技术就是对“非对称密钥加解密”和“数字摘要“两项技术的应用,它将摘要信息用发送者的私钥加密,与原文一起传送给接收者。 接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用HASH函数对收到的原文产生一个摘要信息,与解密的摘要信息对比。 如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过,因此数字签名能够验证信息的完整性。数字签名的过程如下:

明文 --> hash运算 --> 摘要 --> 私钥加密 --> 数字签名

数字签名有两种功效:

  • 能确定消息确实是由发送方签名并发出来的,因为别人假冒不了发送方的签名。
  • 数字签名能确定消息的完整性。

真个HTTPS的握手过程如下

金沙棋牌app手机下载 4image.png

补充:SSH(Secure Shell)的原理和处理过程


首先,需要知道几种不同的SSH Key,

  • HOST KEY 由服务端创建, 用于对服务端进行认证
  • User Key 由用户创建, 用于对用户进行验证
  • Server Key 服务端创建(有效期默认为1小时) 用于加密Session Key--在SSH-2中作为一个概念而存在
  • Session Key 存在于会话中, 用于对传输的数据进行加密

类似上文的SSL/TLS, SSH原理与之很相似.

需要以下几个阶段:

  • 协议协商阶段 (就如同HTTPS交换信息一样)
  • 服务端认证阶段
  • 客户端认证阶段
  • 传输阶段

什么是协议?

你应该听说过 IP 协议,TCP 协议。
所谓协议,是程序员在编程时,大家对发送的数据格式采用的一种共同结构,也就是标准数据结构。

比如, HTTP 请求头的协议采用

GET /demo HTTP/1.1n
Host: www.google.comn
Connection: keep-aliven 

这样的格式,每一个厂商在开发的网络软件都遵循这一标准。这样在另一个接受端,可以采用相同的解析代码来编程。

5. 总结

HTTPS不是不可破解的,并且SSL协议必须随着新攻击被发现和压制而不断发展。但它仍然是一种传递秘密数据的的方式,无需关心谁看到您的消息。当然,这里没有提到许多实现细节,例如握手消息的确切格式和顺序,在不需要重新协商密钥和密码套件的情况下选择最近会话的简短握手,以及在每个阶段可用的众多不同的加密选项。关键要记住的是,虽然HTTPS可以保证数据安全地连接到目的地,但它绝不会保护您(作为用户或开发人员)抵御XSS或数据库泄漏或任何其他事情 。看看威尔史密斯,“Walk in shadow, move in silence, guard against extra-terrestrial violence”。

参考文章:

阶段一:协商

SSH服务器会打开默认的22端口等待客户端的连接, 一旦客户端发起TCP连接请求, 服务端收到后就会向客户端发送SSH协议版本信息.

接着客户端就会根据版本信息与自己的版本,决定选用哪个版本的,发送给服务端.

服务端进行检查自己是否支持客户端决定选用的SSH版本, 在该过程中, 如果发现版本不兼容的情况, 任何一方都可以直接中断连接.

什么是 OpenSSL?

OpenSSL 是在程序上对 SSL 标准的一个实现,提供了:

  • libcrypto 通用加密库
  • libssl TLS/SSL 的实现
  • openssl 命令行工具

程序员可以通过免费开源的 OpenSSL 库来对自己的应用程序提供 SSL 加密。OpenSSL 由 Eric A. Young 和 Tim J. Hudson 在 1995 年提出。1998年,OpenSSL 项目组接管,并制定标准规范。

阶段二: 认证

此时,双方已经建立了通信通道, 要注意,此时的通道依然是明文传输. 服务端发送Host Key&Server Key带上一个128位的MD5(由一个8字节的随机数生成,用来防止IP地址欺诈),客户端收到后,会先到~/.ssh/known_hosts文件中检查是否已经包含,如果没有会发出警告,询问用户是否要信任该主机,并附上其RSA指纹.

The authenticity of host 'host (12.18.429.21)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?

如果有,就会进行下一步.

接着,客户端向服务器端发送Session Key, 这个时候是建立SSH隧道中最需要保密,最重要的时刻,因为session key维系着数据传输的保密性.一旦Session key泄露,整个SSH的安全机制就会变得荡然无存, 因此客户端会使用Host key和Server key对这个session key进行双重加密.

服务器端收到这个Session key,一个安全的通道就被建立起来了,双方会通过这个Session key进行数据的加密和解密.另外,在正式这个通道前, 服务端会再次要求客户端发送Session Key加密的确认信息,如果无误, 则完成服务端的认证过程.

对于客户端的认证,最常见的两种认证方式就是password和public key, 由于password的方式是一般调用的本地系统接口.因此其配置简单(或者说无需配置), 但是暴力破解是可能的.

较好的方式是使用public key的方式.

下面简单说一下, 这种方法的运作流程.

  1. 客户端发起一个Public Key的认证请求,并发送RSA Key的模数作为标识符.
  2. 服务端检查是否存在请求帐号的公钥(Linux中存储在~/.ssh/authorized _ keys文件中),以及其拥有的访问权限。如果没有则断开连接
  3. 服务端使用对应的公钥对一个随机的256位的字符串进行加密,并发送给客户端
  4. 客户端使用私钥对字符串进行解密,并将其结合session id生成一个MD5值发送给服务端。 结合session id的目的是为了避免攻击者采用重放攻击(简单的说就好像是模拟发送一个一样的请求,就像经常在Fiddier进行的一样,也可以理解成窃听到身份token,然后发送给服务端,从而获得token所有者的身份权限)
  5. 服务端采用同样的方式生成MD5值与客户端返回的MD5值进行比较,完成对客户端的认证.

什么是 SSH?

你可能应该听说过 telnet,一个不安全的通过命令行进行服务器客户端通信的工具。
SSH 是使用 OpenSSL 加密的这样的通信工具,提供了更多安全功能。

服务器安装 $ sudo aptitude install openssh-server
服务器启动 $ sudo service ssh start

客户端连接 $ ssh xiaoming@192.168.1.101

Now, let's go.

<h2 id="openssl">从 OpenSSL 开始</h2>

首先,Node.js 是完全采用 OpenSSL 进行加密的,其相关的 TLS HTTPS 服务器模块和 Crypto 加密模块都是通过 C++ 在底层调用 OpenSSL 。

OpenSSL --> crypto --> tls --> https

OpenSSL 实现了对称加密:

AES(128) | DES(64) | Blowfish(64) | CAST(64) | IDEA(64) | RC2(64) | RC5(64)

非对称加密:

DH | RSA | DSA | EC

以及一些信息摘要:

MD2 | MD5 | MDC2 | SHA | RIPEMD | DSS

其中信息摘要是一些采用哈希算法的加密方式,也意味着这种加密是单向的,不能反向解密。这种方式的加密大多是用于保护安全口令,比如登录密码。这里面我们最长用的是 MD5 和 SHA (建议采用更稳定的 SHA1)。

  1. 安装

    安装很简单,从 openssl.org 下载后:

    $ ./configure
    $ make
    $ make install
    

    或者你也可以简单的通过

    $ apt-get install openssl
    $ aptitude install openssl
    

    另外,你可能需要安装一些依赖包:

    $ aptitude install libssl-dev
    
  2. 常用命令

    前面说了,OpenSSL 提供了加密库和一个命令行工具用来管理加密,我们现在来看一下 OpenSSL 的一些常用命令:

    $ openssl s_client -connect 127.0.0.1:8000          // 连接服务器
    
    $ openssl version -a                                // 显示版本和编译参数
    $ openssl ?                                         // 显示支持的子命令
    $ openssl ciphers                                   // 显示 SSL 密码组合列表
    
    $ openssl speed [name]                              // 测试算法速度
    
    $ openssl enc -e -rc4 -in ./file1 -out ./file2      // 加密文件
    $ openssl enc -d -rc4 -in ./file2 -out ./file1      // 解密文件
    
    $ openssl sha1 < ./file1                            // 计算 hash 值 
    
    $ openssl genrsa -out ./a.key 1024                  // 生成 RSA 密钥对
    $ openssl rsa    -in  ./a.key -pubout -out ./a.pub  // 从密钥中提取公钥
    
              密钥位数 : 1024 | 2048 | 4096
    

    openssl genrsa 是常用的生成密钥公钥的命令,-out 文件路径 是输出的文件路径。

<h2 id="tls">TLS HTTPS 服务器</h2>

想要建立一个 Node.js TLS 服务器,需要使用 tls 模块:

var Tls = require('tls');

在开始搭建服务器之前,我们还有些重要的工作要做,那就是证书,签名证书。

基于 SSL 加密的服务器,在与客户端开始建立连接时,会发送一个签名证书。客户端在自己的内部存储了一些公认的权威证书认证机构,即 CA。客户端通过在自己的 CA 表中查找,来匹配服务器发送的证书上的签名机构,以此来判断面对的服务器是不是一个可信的服务器。

如果这个服务器发送的证书,上面的签名机构不在客户端的 CA 列表中,那么这个服务器很有可能是伪造的,你应该听说过“中间人攻击”。

+------------+                                
| 真正的服务器 |             选择权:连接?不连接?  +-------+
+------------+             +------------------ | 客户端 |
                    https  |                   +-------+
+--------------+           | 拦截通信包       
| 破坏者的服务器 | ----------+
+--------------+  证书是伪造的

如果你使用 $ openssl s_client -connect www.site.com,会发现屏幕上为你显示 self signed certificate。

如果你以前使用 firefox 浏览器造访过著名的 12306,会收到一个“不信任的连接,是否仍然连接”的页面,来给你提供一个安全提示的选择。

OO,有些东西就是很逗,不是么!

存在即是合理的!

让我们嘲笑这个逗比一样的话,有时候存在是因为愚昧无知,而不是合理。

兔子不吃窝边草.
近水楼台先得月.

这种自我矛盾的蠢话多的是呀!不要当真!

看到这里,你也应该明白为什么最近 Google 和 Mozilla 一直在推进 HTTPS 和 HTTP 2.0。

  1. 让我们来伪造证书

    基于测试的目的,我们现在表演一下整个制造证书的过程。构建 TLS HTTPS 服务器,需要:

    • 密钥
    • 证书签发申请
    • 权威机构对证书签发申请签名后的证书

    第3个需要每年缴纳几千元人民币,以维持安全证书的认证费用。从程序员角度来讲,我们可以自己签名,从而创建一个不受信任的证书。(仅限于研究使用,如果你用在自己的服务器上,你的服务器就会有被别人冒充的风险)

    所有这些需要使用 OpenSSL 来实现:

    1. 生成密钥

      $ openssl genrsa -out ./ca-key.pem 1024

    这条命令为你生成一个 1024 位长度的加密密钥,放在你的当前目录中的 ca-key.pem 文件中。
    这个文件的内容是类似这样的,每行以一个 'n' 换行符:

    -----BEGIN RSA PRIVATE KEY-----
    MIICXQIBAAKBgQDEw2LYED8+AgLHOtrwXLCXCm2okHOh6Wx7FJ5GVlsdMysJRD8r
    dTfTr3kRo/wKssZgGBydIrUPxk6Nvywdcp0V2yp5NjlruvgIkTFL/tkecJumuLc3
    XtQ1J2GwLCqkUjpnll9MzKENCpNeX1BDSJNJ6QRkXRk/13nY4HArdrHdEQIDAQAB
    AoGAGnNRlE4K0mEe0n189Rbgvk0ulJxmjvt8E8efx0DQmspIHMTJ4SOuz4wlMFPl
    C+Mge8aCAjWqNWapJLDwUz0XFJ6yd/nvF7Ludc97NB95uSDeuY/nFVQnAbSAd9sS
    uD/cCJLLZ+8XmeUktUSP9cCR6zGgkvPEPOXreFg3xqVDjIkCQQDolDRT14UvaxMC
    f6JyjHZ8bj7FDQyqBj+hQFAB4WVA2q4pZ+WGUJpqwTb4WvfW27tX/DnHZkVSuFGa
    j2z8mc67AkEA2JPd5DYIqIu3m5D0YaWdIIYi5FyL5ecRuXEKv5GexIlhePBZqT2l
    zXt9yI6YUOQjeOusOy2kRSqm9IMnDhv0owJBAMdpYuBMFo6MkNUAmEj8tA6F+926
    DZSuHNpmKPMjzUvo85De2wXpkCxeE4KnhH49EgkjYmrb/i4piRYrSTffrEcCQQCx
    I8gyVyufx58mY1ou38lzh6LUSwm1wdgSZ+4Vn+JO99q8k0GSljSdq6rGtjLIvsBw
    r7oQMRWR6P/jL75q4NynAkBYQKBDWPiSCGmu0vr0uf3qLhtZjMenBZ2Z9qWdBGKW
    CNGxpKgdFeM05XpUg/cJOS/fcvMV2GcMldI62k3JwoBF
       -----END RSA PRIVATE KEY-----
    
    1. 生成证书签发申请

      $ openssl req -new
      -key ./ca-key.pem
      -out ./ca-csr.pem

    这条命令,通过对方刚才生成的密钥 ca-key.pem,生成一个证书签发申请 ca-csr.pem,然后你应该把这个发送给认证机构为你签名,并缴纳费用,获得一个权威的认证证书。

    这个文件的内容类似这样:

     -----BEGIN CERTIFICATE REQUEST-----
     MIIBhDCB7gIBADBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEh
     MB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEB
     AQUAA4GNADCBiQKBgQDEw2LYED8+AgLHOtrwXLCXCm2okHOh6Wx7FJ5GVlsdMysJ
     RD8rdTfTr3kRo/wKssZgGBydIrUPxk6Nvywdcp0V2yp5NjlruvgIkTFL/tkecJum
     uLc3XtQ1J2GwLCqkUjpnll9MzKENCpNeX1BDSJNJ6QRkXRk/13nY4HArdrHdEQID
     AQABoAAwDQYJKoZIhvcNAQEFBQADgYEAMs/iPk5wyhpp6LUib4d93d8Yv5/5hIt+
     EiPTU0KQRIhJtt+mGAipgsPC5KWgIPii+/cQbx0M/1/QJLnlW2DiNKc7sOQiJza3
     7BoO9VtJl+ufZ7B1CjEfTWNHHOvA2vYhCKcBPOQXf+E9MbjWznAPwTmjmCznHtWo
     RVQ8R4sSCKo=
     -----END CERTIFICATE REQUEST-----
    
    1. 对证书签发申请进行签名,生成签名证书

    这里,我们来制造一个自签名的证书,这是一个不受信任的证书,实际服务器中你不应该使用。

     $ openssl x509 -req  
                    -days    9999             
                    -signkey ./ca-key.pem     
                    -in      ./ca-csr.pem     
                    -out     ./ca-cert.pem
    

    使用前面生成的密钥、证书签发申请,生成 ca-cert.pem 文件。这个文件的内容类似这样:

     -----BEGIN CERTIFICATE-----
     MIICATCCAWoCCQCphVNXJELjIjANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB
     VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
     cyBQdHkgTHRkMB4XDTE1MDcxMTAxMTg1OVoXDTQyMTEyNTAxMTg1OVowRTELMAkG
     A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
     IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxMNi
     2BA/PgICxzra8FywlwptqJBzoelsexSeRlZbHTMrCUQ/K3U30695EaP8CrLGYBgc
     nSK1D8ZOjb8sHXKdFdsqeTY5a7r4CJExS/7ZHnCbpri3N17UNSdhsCwqpFI6Z5Zf
     TMyhDQqTXl9QQ0iTSekEZF0ZP9d52OBwK3ax3RECAwEAATANBgkqhkiG9w0BAQUF
     AAOBgQAjNF0fWyI/XLegpj2dnk+RQXJTljRtcBuJ+qU2IGknTT5NpqiRaCxWyH52
     rD4ZEV8GVPJ8BqarKuYPubqumd7KXa2Ulyf73dGHyvaykgqxi8Vm+B9G2Sfukdt8
     vLQ1fy39qF5ZnTVMR/4KaYbFa7jXHSxdJak395D1OUNJBv3rqA==
     -----END CERTIFICATE-----
    
    1. 验证证书的签名

如果你想实验的话,可以使用 OpenSSL 对证书签名进行验证:

     $ openssl verify -CAfile ca-cert.pem ca-cert.pem

 这是对两个签名证书核对,一个是服务端发送的证书,一个是客户端自己的证书,实际过程中更像是这样:

     $ openssl verify -CAfile server-cert.pem client-cert.pem

 浏览器内部会为你完成这个过程。如果你有使用过淘宝安全证书的话,会对此有一些理解。
 Node.js TLS HTTPS 服务器也会在内部完成这一过程。
  1. TLS 服务器 HTTPS 服务器

    构建 TLS 服务器非常简单,而且是基于 epoll kqueue 这样的高 IO 模型。

    var Tls = require('tls');
    var Fs  = require('fs');
    
    var server = Tls.createServer({
        key                : Fs.readFileSync('./ca-key.pem'),   // 服务器密钥
        cert               : Fs.readFileSync('./ca-cert.pem'),  // 服务器签名证书
        handshakeTimeout   : 120,                               // 握手超时时间,default=120s
        ca                 : [],                                // 有效证书认证机构
        passphrase         : '123456',                          // 服务器密钥解析密码
        requestCert        : true,                              // 客户端需要发送签名证书
        rejectUnauthorized : true                               // 客户端发送的证书必须是有效认证机构签名
        // ciphers          : '',                               // 加密组件
        // ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL
        // secureProtocol : secureProtocol,                     // 强制使用版本的安全协议
        // secureOptions  : secureOptions                       // 安全方法配置 
    });
    server.listen(10010);
    server.on('secureConnection', function (socket) {
        console.log('Authorized: ',         socket.authorized);            // 客户端签名证书是 CA 签名?
        console.log('AuthorizationError: ', socket.authorizationError);    // 验证错误原因
        console.log('Certificate: ',        socket.getPeerCertificate());  // 客户端签名证书信息
        console.log('Cipher: ',             socket.getCipher());           // 当前加密组件的信息
    
        socket.setEncoding('utf8');
        socket.on('data', function (data) {
            console.log('Data: %j', data);
        });
        socket.on('end', function () {
            console.log('End');
        });
    
        process.stdin.pipe(socket);
        process.stdin.resume();
    });
    server.on('newSession', function (sessionId, sessionData) {
        console.log('SessionId',            sessionId);
        console.log('SessionData',          sessionData);
    });
    

    如果愿意的话,你可以自己写一个 SSH!

    TLS.Server 模块继承自 Net.Server,为其扩充了 SSL 内容,所有的其他操作跟 Net.Server 一模一样。

    Tls.createServer(options, [listener]) 其中的 options 提供了 SSL 配置。

    • ca 是一个权威认证机构的列表,用于服务器查找客户端的签名证书是不是伪造的
    • key 你的密钥字符串或者 Buffer,只需要 readFileSync() 你的密钥文件即可
    • cert 你的证书字符串或者 Buffer,只需要 readFileSync() 你的证书文件即可
    • handshakeTimeout 服务器客户端连接认证会进行加密算法操作,如果时间过长,就断开连接。如果你不想自己配置这一项,那么默认是 120 秒
    • passphrase 当生成密钥时,会请你为文件输入一个解析密码,也可以输入空,这一项就是为服务器提供解析文件的密码
    • requestCert 要求客户端必须发送证书,不然就断开连接
    • rejectUnauthorized 要求客户端的证书必须是 CA 认证的,不然就断开连接,当测试的时候应该设置为 false,当用于生产时,应该设为 true
    • ciphers 使用的 OpenSSL 加密组件,这个可以不设置,采用系统默认的。除非遇到重大漏洞需要修改的时候

    需要重要考虑的配置项大体是以上内容。

    'secureConnection' 是 TLS 服务器特有的事件,当安全认证成功的时候触发。

    你可以使用 OpenSSL 来测试下你的 TLS 服务器:

    $ openssl s_client -connect 127.0.0.1:10010  
    

    对于 HTTPS 服务器,更简单了,他是 TLS 服务器的继承,

    var Https = require('https');
    https.createServer(options);
    

    其中的 options 跟 TLS 服务器一模一样,其余的操作跟 http.Server 是一样的。

    net.socket --> net.Server --> http.Server
    
    net.socket --> tls.TLSSocket + net.Server --> tls.Server + http.Server --> https.Server
    
  2. TLS HTTPS 客户端

    编写 TLS 客户端,相比 TCP 客户端,也仅限于 options 上的变化:

    var Tls = require('tls');
    var Fs  = require('fs');
    
    var socket = Tls.connect({
        port               : 10010,
        key                : Fs.readFileSync('./ca-key.pem'),   // 客户端密钥
        cert               : Fs.readFileSync('./ca-cert.pem'),  // 客户端签名证书
        ca                 : [],                                // 有效证书认证机构
        passphrase         : '123456',                          // 客户端密钥解析密码    
        rejectUnauthorized : true                               // 服务器发送的证书必须是有效认证机构签名
        // secureProtocol   : ''                                // 安全协议
    }, function() {
        console.log('client connected', socket.authorized ? 'authorized' : 'unauthorized');
        process.stdin.pipe(socket);
        process.stdin.resume();
    });
    socket.setEncoding('utf8');
    socket.on('data', function (data) {
        console.log('Data: %j', data);
    });
    socket.on('end', function () {
        console.log('End');
        socket.end();
    });
    socket.on('error', function (err) {
        console.log('Error: ', err);
    });
    

<h2 id="crypto">Crypto 加密解密</h2>

Node.js 中的 TLS HTTPS 服务器的加密操作都来自 crypto 模块,而 crypto 则是对 OpenSSL 库的调用。重要的细节不再讨论了,只给出实际的使用方法,具体参数可以参考官方文档。

  1. 哈希加密 (单向)

    • Hash 普通哈希加密
    • Hmac 带有密钥的哈希加密

    Hash 加密:

    var hash   = Crypto.createHash('sha1');
    var result = hash.update('a')
                     .update('a') 
                     .digest('hex'); 
    

    输出 e0c9035898dd52fc65c41454cec9c4d2611bfb37 这样使用 sha1 算法的16进制字符串。

    你会看到 update() 调用两次,实际上这个方法可以不停调用,上边的

    .update('a')
    .update('a')
    

    等同于

    .update('aa')
    

    Hmac 加密:

    var hmac   = Crypto.createHmac('sha1', '123456');
    var result = hmac.update('a')
                     .update('a') 
                     .digest('hex');
    

    输出 ba0572b07799c0fa754a669604323537cdabeb79。这个加密提供了 '123456' 这样的可以设置密钥,你可以为其设置上面通过 OpenSSL 生成的密钥字符串,这样的加密级别更高。

  2. 加密解密 (双向)

    Cipher 和 Decipher 分别是 Node.js 提供的可操作的加密和解密抽象。使用方式如下:

    Cipher 加密 abc010:

    var cipher = Crypto.createCipher('aes192', '123456');
    cipher.update('abc',  'utf8'); 
    cipher.update('010', 'binary');
    var result = cipher.final('hex');
    

    输出 a16a2e4e1b22f3c824f159d3b5800c06。一个使用 aes192 算法加密过的字符串。

    Decipher 解密 a16a2e4e1b22f3c824f159d3b5800c06:

    var decipher = Crypto.createDecipher('aes192', '123456');
    decipher.update('a16a2e4e1b22f3c824f159d3b5800c06', 'hex'); 
    var result   = decipher.final('utf8');
    

    输出 abc010,原始的数据。

  3. 签名和认证

    Sign 和 Verify 是对 OpenSSL 签名认证的封装。

    Sign 签名:

    var sign   = Crypto.createSign('RSA-SHA256');
    var result = sign.update('abc')
                     .update('010')
                     .sign(
    // 密钥
    `-----BEGIN RSA PRIVATE KEY-----
    MIICXQIBAAKBgQClyE/ApYk91LDdnhM8qIyukbl1p1Ek3z/5bAKq7bCyfevtw3DI
    JIwJIyHpGjnosR6/4phApcOqTpLNVJ/Nc0AKWwZcEFlRO7Uty3EFBU8EbTTiCV2N
    NKYJIvGnxV+43ubyuYla/RjwylOktUyTVHvMz4o3mVohW4FLaEiRu6rEIQIDAQAB
    AoGBAJGdLE/uFmn005UVL5hsA4WiAeBRonhcj3ipYn54YGenKv+gVwO09jtgXHy+
    yHaWfIfWpBzEfOSuN0ubNPHkdS45cEtgWtvX6OYuMWNr64YRW6YevxDr4Ui7bGdh
    a+Zk0fkmchjvrgycD8MDLbqTFIyFkMAd6VUOY7YVRNlxMq8xAkEA0HcxdeUCrruS
    JkXmGMt5g1HkJXrqpbRuQ4vPwQM+q6QuT5fk44MGj0U42feqFWfwMnPGAh6dkN0E
    nS3kC6UyuwJBAMuVkRmeAM0HkB883e9rCdnsIzfqLdCFiOKKmdrBlxqfHlEqp8bD
    2DgMYTS3s+3yQqQuBjkRxNQ5/Fw7E+lInNMCQC+PghFLtlj3IljpCZ4OjiKPxGVo
    rbAwgheXBkca3ml6g7ZVCTt+4Tg+qsHP51YK6JoaH8rMAVbTlgHmPmkJv5ECQGmz
    l2nQkqPheF/vr19+mNfP9h0y9mSc4IyW3/knqHfHA+uqlP/rcVjwfIvtkXtK3HT3
    /H0nD6YNEU0l01m9PMcCQQCGtxn5szckko+6ketDhuJpNlUxU4gux0TidgDRkDQp
    iF8QnAVbE6kDLlw/M1/Kf5mXS4+EssVzy1pUx0fZpgAw
    -----END RSA PRIVATE KEY-----`, 
    // 签名编码
    'hex');
    

    如你所看到的,这些方法需要一个使用 OpenSSL 生成的密钥,然后为其生成一个不受信任的签名。
    生成一个字符串:

    53e8f22eb539be7d37a2c1d2dc5c0d7c1f974626e11dee
    8085f47d4b7afb004e7d06639c431be622070786cc4d68
    dbc3f22f69bc3bc431d60128c78657045108b5068e9f54
    e1af6966330852857e5f697a2e4d3b9a30849f3b373344
    5f7c76251f88ddd48fbf53be444f6d817f1e7ef2784d67
    556e39310e1cc405f5ddef2dfc
    

    Verify 认证证书:

    var verify = Crypto.createVerify('RSA-SHA256');
    var result = verify.update('abc')
                       .update('010')
                       .verify(
    // 公钥
    `-----BEGIN CERTIFICATE-----
    MIICWDCCAcGgAwIBAgIJAO5P5yii8BuLMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
    BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
    aWRnaXRzIFB0eSBMdGQwHhcNMTUwNzA5MTAzNDI3WhcNMTUwODA4MTAzNDI3WjBF
    MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
    ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
    gQClyE/ApYk91LDdnhM8qIyukbl1p1Ek3z/5bAKq7bCyfevtw3DIJIwJIyHpGjno
    sR6/4phApcOqTpLNVJ/Nc0AKWwZcEFlRO7Uty3EFBU8EbTTiCV2NNKYJIvGnxV+4
    3ubyuYla/RjwylOktUyTVHvMz4o3mVohW4FLaEiRu6rEIQIDAQABo1AwTjAdBgNV
    HQ4EFgQUGsVvaLFUxW+hMc/jVpvQXH5hzL0wHwYDVR0jBBgwFoAUGsVvaLFUxW+h
    Mc/jVpvQXH5hzL0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQAXS8da
    q3Ybw3+KvIZz/tAGLkPshv4J7jwIKNvlZeMX0dGZsd1faZJyrCmzZ7Go43L24zqg
    rAwXOlfz+pjoGEaQSyTXOJX23ZozCGEzI2OgmLxLuk2Wfn3OUiQK8RqjrOzXosTR
    3RcofenE7hTk17gjs50aDHc/hu363U3gklxnWA==
    -----END CERTIFICATE-----`, 
    // 签名
    '53e8f22eb539be7d37a2c1d2dc5c0d7c1f974626e11dee' + 
    '8085f47d4b7afb004e7d06639c431be622070786cc4d68' + 
    'dbc3f22f69bc3bc431d60128c78657045108b5068e9f54' + 
    'e1af6966330852857e5f697a2e4d3b9a30849f3b373344' + 
    '5f7c76251f88ddd48fbf53be444f6d817f1e7ef2784d67' + 
    '556e39310e1cc405f5ddef2dfc', 
    // 签名编码
    'hex');   
    

    输入双方认可的公钥,对方的签名,然后输出 true 或者 false 表示双方的证书是否一致。


金沙棋牌app手机下载 5

That's all!

阶段三: 传输

使用Session Key提供的对称加密算法,保证数据传输的安全.

本文由金沙棋牌发布于金沙棋牌app手机下载,转载请注明出处:深入理解HTTPS协议,MsSQL使用加密连接SSL

关键词: