Total Pageviews

Thursday 27 September 2018

深入解析HTTPS


超文本传输安全协议(英语:Hypertext Transfer Protocol Secure,缩写:HTTPS,常称为HTTP over TLS,HTTP over SSL或HTTP Secure)是一种网络安全传输协议。在计算机网络上,HTTPS经由超文本传输协议进行通信,但利用SSL/TLS来加密数据包。HTTPS开发的主要目的,是提供对网络服务器的身份认证,保护交换数据的隐私与完整性。这个协议由网景公司(Netscape)在1994年首次提出,随后扩展到互联网上。
HTTPS连接经常用于万维网上的交易支付和企业信息系统中敏感信息的传输。
http协议直接放置在TCP协议之上,而HTTPS提出在http和TCP中间加上一层加密层。从发送端看,这一层负责把http的内容加密后送到下层的TCP,从接收方看,这一层负责将TCP送来的数据解密还原成http的内容。所以严格地讲,HTTPS并不是一个单独的协议,而是对工作在一加密连接(TLS或SSL)上的常规HTTP协议的称呼。
下面是一个简单的HTTPS协议栈的图:

HTTPS流程步骤

上面已经说过HTTPS主要是加了一层SSL/TLS加密,那么具体是如何进行加密,解密,验证的,且看下图:
1. 客户端发起HTTPS请求
这个没什么好说的,就是用户在浏览器里输入一个https网址,然后连接到server的443端口。
2. 服务端的配置
采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl就是个不错的选择,有1年的免费服务)。这套证书其实就是一对公钥和私钥。如果对公钥和私钥不太理解,可以想象成一把钥匙和一个锁头,只是全世界只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。
3. 传送证书
这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。
4. 客户端解析证书
这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随即值。然后用证书对该随机值进行加密。就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容。
5. 传送加密信息
这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。
6. 服务端解密信息
服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密。所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。
7. 传输加密后的信息
这部分信息是服务段用私钥加密后的信息,可以在客户端被还原
8. 客户端解密信息
客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容。整个过程第三方即使监听到了数据,也束手无策。

SSL/TLS概念

SSL/TLS是加密通信协议,SSL由NetScape在1994年设计,1999年互联网标准化组织ISOC接替NetScape公司,发布了SSL的升级版TLS 1.0版。现在主流的浏览器等都支持TLS1.2版本,如iOS9中新增App Transport Security(简称ATS)特性,强制http转向https,其中加密通信协议就需要TLS1.2及以上版本。
SSL/TLS协议的基本思路是采用公钥加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。
SSL/TLS协议的基本过程是这样的:
(1) 客户端向服务器端索要并验证公钥。
(2) 双方协商生成"对话密钥"。
(3) 双方采用"对话密钥"进行加密通信。
所以说SSL/TLS协议主要是包含非对称加密(公钥加密)和对称加密,用非对称加密来得到对称加密的"对话秘钥",然后用对称加密来进行加密通信。

两个问题

如何保证公钥不被篡改?
解决方法:将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。那如何保证证书是可信的呢?证书由CA机构进行颁发,而游览器内置了这些CA机构的根证书,只要由这些CA机构办法的数字证书即是可信的。
为什么不直接使用公钥加密,还要加上个对称加密?
公钥加密是非对称加密,加密计算量大,而对称加密运算速度非常快。所以这里只有第一次握手时进行公钥加密来得到对称加密的"对话密钥",之后的通信就使用对称加密来进行通信了。

加密算法

  • 对称密码算法
是指加密和解密使用相同的密钥,典型的有DES、RC5、IDEA(分组加密),RC4(序列加密);
  • 非对称密码算法
又称为公钥加密算法,是指加密和解密使用不同的密钥(公开的公钥用于加密,私有的私钥用于解密)。比如A发送,B接收,A想确保消息只有B看到,需要B生成一对公私钥,并拿到B的公钥。于是A用这个公钥加密消息,B收到密文后用自己的与之匹配的私钥解密即可。反过来也可以用私钥加密公钥解密。也就是说对于给定的公钥有且只有与之匹配的私钥可以解密,对于给定的私钥,有且只有与之匹配的公钥可以解密。典型的算法有RSA,DSA,DH;
  • 散列算法
散列变换是指把文件内容通过某种公开的算法,变成固定长度的值(散列值),这个过程可以使用密钥也可以不使用。这种散列变换是不可逆的,也就是说不能从散列值变成原文。因此,散列变换通常用于验证原文是否被篡改。典型的算法有:MD5,SHA,Base64,CRC等。

关于CA及数字证书

什么是CA

CA(Certificate Authority)是数字证书认证中心的简称,是指发放、管理、废除数字证书的机构。
CA的作用是检查证书持有者身份的合法性,并签发证书(在证书上签字),以防证书被伪造或篡改,以及对证书和密钥进行管理。
CA 也拥有一个证书(内含公钥)和私钥。网上的公众用户通过验证 CA 的签字从而信任 CA ,任何人都可以得到 CA 的证书(含公钥),用以验证它所签发的证书。
如果用户想得到一份属于自己的证书,他应先向 CA 提出申请。在 CA 判明申请者的身份后,便为他分配一个公钥,并且 CA 将该公钥与申请者的身份信息绑在一起,并为之签字后,便形成证书发给申请者。
如果一个用户想鉴别另一个证书的真伪,他就用 CA 的公钥对那个证书上的签字进行验证,一旦验证通过,该证书就被认为是有效的。

证书的内容

数字证书的格式遵循X.509标准,X.509是由国际电信联盟(ITU-T)制定的数字证书标准,规范了公开密钥认证、证书吊销列表、授权证书、证书路径验证算法等。
证书的内容包括:电子签证机关的信息、公钥用户信息、公钥、权威机构的签字和有效期等等。
下图就表示一个数字证书包含的内容:

我们这里能看到颁发机构签名是由申请者信息经过哈希算法得到hash值,然后再用机构的私钥进行加密。所以这个签名只有办法机构的公钥才能解密,而一般权威CA机构的根证书(含公钥)都内置在浏览器中,所以客户端接收到这个数字证书后,先把申请者信息用同样的哈希算法得到hash值h1,然后用公钥进行办法机构签名解密得到hash值h2,如果h1==h2,则表示证书是有效的。
下图就是Charles的根证书例子:

编码格式

同样的X.509证书,可能有不同的编码格式,目前有以下两种编码格式。
PEM - Privacy Enhanced Mail,打开看文本格式,以"-----BEGIN..."开头, "-----END..."结尾,内容是BASE64编码.
查看PEM格式证书的信息:openssl x509 -in certificate.pem -text -noout
Apache和*NIX服务器偏向于使用这种编码格式.
DER - Distinguished Encoding Rules,打开看是二进制格式,不可读.
查看DER格式证书的信息:openssl x509 -in certificate.der -inform der -text -noout
Java和Windows服务器偏向于使用这种编码格式.

相关的文件扩展名

这是比较误导人的地方,虽然我们已经知道有PEM和DER这两种编码格式,但文件扩展名并不一定就叫"PEM"或者"DER",常见的扩展名除了PEM和DER还有以下这些,它们除了编码格式可能不同之外,内容也有差别,但大多数都能相互转换编码格式。
CRT - CRT应该是certificate的三个字母,其实还是证书的意思,常见于*NIX系统,有可能是PEM编码,也有可能是DER编码,大多数应该是PEM编码,相信你已经知道怎么辨别.
CER - 还是certificate,还是证书,常见于Windows系统,同样的,可能是PEM编码,也可能是DER编码,大多数应该是DER编码.
KEY - 通常用来存放一个公钥或者私钥,并非X.509证书,编码同样的,可能是PEM,也可能是DER。
查看KEY的办法:openssl rsa -in mykey.key -text -noout
如果是DER格式的话:openssl rsa -in mykey.key -text -noout -inform der
CSR - Certificate Signing Request,即证书签名请求,这个并不是证书,而是向权威证书颁发机构获得签名证书的申请,其核心内容是一个公钥(当然还附带了一些别的信息),在生成这个申请的时候,同时也会生成一个私钥,私钥要自己保管好。
查看的办法:openssl req -noout -text -in my.csr
如果是DER格式的话:openssl req -noout -text -in my.csr -inform der
PFX/P12 - predecessor of PKCS#12,对*nix服务器来说,一般CRT和KEY是分开存放在不同文件中的,但Windows的IIS则将它们存在一个PFX文件中,(因此这个文件包含了证书及私钥)这样会不会不安全?应该不会,PFX通常会有一个"提取密码",你想把里面的东西读取出来的话,它就要求你提供提取密码,PFX使用的时DER编码,如何把PFX转换为PEM编码?
openssl pkcs12 -in for-iis.pfx -out for-iis.pem -nodes
这个时候会提示你输入提取代码. for-iis.pem就是可读的文本。
生成pfx的命令类似这样:openssl pkcs12 -export -in certificate.crt -inkey privateKey.key -out certificate.pfx -certfile CACert.crt
其中CACert.crt是CA(权威证书颁发机构)的根证书,有的话也通过-certfile参数一起带进去.这么看来,PFX其实是个证书密钥库.
JKS - 即Java Key Storage,这是Java的专利,跟OpenSSL关系不大,利用Java的一个叫"keytool"的工具,可以将PFX转为JKS,当然了,keytool也能直接生成JKS,不过在此就不多表了。

证书编码的转换

  • .crt转.der方法
openssl x509 -in cert.crt -out cert.der -outform DER
  • .crt转.cer方法
openssl x509 -in cert.crt -out cert.cer -outform DER
  • .crt转.pem方法
openssl x509 -in cert.crt -out cert.pem -outform PEM

生成自签名证书的步骤

建立CA

  • 在任意目录建立文件夹,文件夹名称任意
mkdir ca
  • 进入到新建立的文件夹ca
cd ca
  • 生成CA私钥
openssl genrsa -out ca.key 2048
  • 用CA私钥生成CA的证书
openssl req -new -x509 -days 36500 -key ca.key -out ca.crt -subj "/C=CN/ST=Hangzhou/L=Hangzhou/O=Teamsun/OU=Dasheng" 
  • 建立CA相应目录
 mkdir demoCA

 cd demoCA/
 
 mkdir newcerts

 touch index.txt

 echo '01' > serial

生成server端证书

  • 进入ca文件夹
cd ca
  • 生成server私钥
openssl genrsa -out server.key 2048
  • 使用server私钥生成server端证书请求文件
openssl req -new -key server.key -out server.csr -subj "/C=CN/ST=Hangzhou/L=Hangzhou/O=Teamsun/OU=dasheng/CN=dasheng"
  • 使用server证书请求文件通过CA生成自签名证书
openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key
  • 验证server证书
openssl verify -CAfile ca.crt server.crt

测试

  • 使用server证书测试单向认证
  1. 打开窗口1启动server
openssl s_server -accept 10001 -key server.key -cert server.crt
  1. 打开窗口2启动客户端
openssl s_client -connect localhost:10001
  1. 连接成功后在任意一个窗口输入字符串会传输到另外一个窗口回显。

脚本

快速创建证书的脚本
使用(host表示证书用于的域名,cerFile表示证书保存的目录):
sh ./generate_certificate.sh host cerFile

信任自签名证书

查看证书链

Chrome57及后续版本Chrome浏览器用户如要查看SSL证书信息只能通过开发者工具(右键->检查),选择安全标签(Security)进行查看了。然后点击View certificate查看证书链,如下图为查看www.google.com的证书链:

信任证书

在MAC上直接双击证书,然后在钥匙串里就能看到这个证书了,我们能看到证书上会显示此证书是由不被信任的签发者签发的此根证书不被信任。然后我们再在钥匙串中双击证书->信任->使用此证书时:始终信任
这里我们可以信任两种证书:CA根证书和CA签名过的数字证书。两种证书在钥匙串中显示的颜色是不一样的。
下图就是自己创建的两种证书:

我们信任两种证书都可以使请求变成安全的请求,在浏览器中输入的时候就不会有不安全的提示了。这里说一下为什么两种证书都可以。
首先说CA根证书,这种就是我们正常的流程,CA根证书用公钥解密数字证书的签名得到hash值,然后根据hash值相等判断证书有效。
而不信任根证书只信任数字证书,就很容易理解了,他们本来就是同一张证书,也不用通过加密解密什么的来判断了。

Chrome信任根证书后提示链接不安全

这里我信任根证书之后还是提示链接不安全:ERR_CERT_WEAK_SIGNATURE_ALGORITHM。而信任数字证书则没问题。发生这种情况的原因是Chrome 57版本以后是不支持SHA-1算出的hash值的证书签名的,而我们上面生成的证书默认为SHA-1,这里只要改为SHA-256就可以了。
//用CA私钥生成CA的证书
openssl req -new -x509 -days 36500 -key ca.key -out ca.crt -subj "/C=CN/ST=Hangzhou/L=Hangzhou/O=Teamsun/OU=Dasheng" -sha256

//使用server证书请求文件通过CA生成自签名证书
openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key -sha256

获取证书小技巧

有时候我们没有这个网站的证书,那要如何得到呢?
  1. 使用openssl能直接得到这个证书:
openssl s_client -connect 172.16.10.244:8000 </dev/null 2>/dev/null | openssl x509 -outform DER > https.cer
```
  1. 直接Safari输入网站,如果是不安全的,会显示下图,然后点击显示证书,勾选连接时始终信任,点击继续证书就添加到钥匙串中了。

iOS中使用自签名证书

iOS9中新增App Transport Security(简称ATS)特性, 主要使到原来请求的时候用到的HTTP,都转向TLS1.2协议进行传输。这也意味着所有的HTTP协议都强制使用了HTTPS协议进行传输。一般如果我们HTTPS服务使用的证书是CA权威机构颁发的话,客户端不用修改任何代码,因为iOS系统已经内置了这些权威机构的根证书。但是如果是自签名的证书的话就需要修改代码来内部信任这部分证书了。

AFNetworking使用自签名证书

AFNetWorking封装了如何使用自签名证书,简单的使用方式如下。
//先导入证书,找到证书的路径
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"cert" ofType:@"der"];
NSData *certData = [NSData dataWithContentsOfFile:cerPath];
NSSet * certSet = [[NSSet alloc] initWithObjects:certData, nil];
    
//AFSSLPinningModeNone 这个模式表示不做 SSL pinning,只跟浏览器一样在系统的信任机构列表里验证服务端返回的证书。若证书是信任机构签发的就会通过,若是自己服务器生成的证书,这里是不会通过的。

//AFSSLPinningModeCertificate 这个模式表示用证书绑定方式验证证书,需要客户端保存有服务端的证书拷贝,这里验证分两步,第一步验证证书的域名/有效期等信息,第二步是对比服务端返回的证书跟客户端返回的是否一致。
    
//AFSSLPinningModePublicKey 这个模式同样是用证书绑定方式验证,客户端要有服务端的证书拷贝,只是验证时只验证证书里的公钥,不验证证书的有效期等信息。只要公钥是正确的,就能保证通信不会被窃听,因为中间人没有私钥,无法解开通过公钥加密的数据。
    
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
// 是否允许,NO-- 不允许无效的证书
[securityPolicy setAllowInvalidCertificates:YES];
// 设置证书
[securityPolicy setPinnedCertificates:certSet];
//是否验证域名信息
securityPolicy.validatesDomainName = NO;

    
AFHTTPSessionManager *manager = [[AFHTTPSessionManager manager] initWithBaseURL:[NSURL URLWithString:@"https://192.168.3.13:8000"]];
manager.securityPolicy = securityPolicy;
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager GET:@"/getInfo" parameters:@{@"t":@"1490927497.569"} progress:^(NSProgress * progress){
} success:^(NSURLSessionDataTask *task, id responseObject) {
    NSArray * array = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableLeaves error:nil];
    NSLog(@"OK === %@",array);
} failure:^(NSURLSessionDataTask *task, NSError *error) {
    NSLog(@"error ==%@",error.description);
}];

证书需要满足的条件

这里的证书使用CA根证书或CA签名的数字证书都可以。
密钥交换算法有RSAECDHE,RSA 历史悠久,支持度好,但不支持 PFS(Perfect Forward Secrecy);而 ECDHE 是使用了 ECC(椭圆曲线)的 DH(Diffie-Hellman)算法,计算速度快,支持 PFS。
  1. iOS支持的秘钥交换算法为:至少2048位的 RSA 密钥至少256位的 ECC 密钥
  2. 服务器证书的哈希算法必须为 SHA-2,其摘要长度至少位256位。
  3. 证书格式为.der,很多网上的教程都写的是.cer,应该是使用的旧版AFNetWorking,最新版的不支持.cer,需要使用.der格式。

中间人攻击

概念

关于Https最常讲到的就是中间人攻击,即所谓的Man-in-the-middle attack(MITM)。也就是攻击者插入原先攻击的双方,让双方以为还在直接跟对方通讯,但实际上双方的通信对方已变成了中间人,信息已经是被中间人获取或篡改。
其实http的中间人攻击是最简单的,因为http都是通过明文传输,而且没有任何认证之类的东西。我们常常用的Charles抓包就是一个最简单的中间人攻击。

对HTTPS进行中间人攻击

我们用Charles进行HTTPS的抓包的时候会发现抓到的包都是加过密的无法查看,那是不是就意味着无法抓取HTTPS的包了呢?其实也是可以的,通过伪造证书,并且客户端又安装了Charles根证书,就可以抓取到HTTPS的包并解密了。
具体的步骤是这样的,手机安装Charles根证书,手机使用Charles的代理,所有请求都经过Charles中间人。Charles劫持到请求,替换服务端的证书为自己的伪证书,然后发送给客户端,客户端使用Charles根证书来验证这个伪证书,验证通过得到公钥,然后用公钥加密对话秘钥发送回Charles中间人,Charles中间人私用私钥解密得到对话秘钥并保存,然后再把对话秘钥用服务端的公钥加密返回给服务端,这样就表示两端握手成功,可以进行通信了。而且中间人也获得了之后的对话秘钥,可以解密之后的对话信息。

Charles实现HTTPS抓包

这里基本的HTTP抓包的设置就不讲了,下面是基于实现基本的HTTP抓包的基础上来实现HTTPS的抓包解密。
  • 安装Charles CA根证书
    点击Help->SSL Proxying->Install Charles Root Certification ...,会弹出如下提示,链接代理,手机浏览器输入chls.pro/ssl,就可以安装根证书了。


  • 设置SSL代理
    点击Proxy->SSL Proxying Setting,勾选Enable SSL Proxying,然后点击Add输入要SSL代理的请求Host和Port,可以使用通配符来表示某一类请求。


    或者在对应的请求上右键选择Enable SSL Proxying,就会把这一个请求加入到上面的SSL代理列表中(类似于点击Add的效果)。

做完上述步骤后重新请求就能得到解密后的信息了。抓取PC端的HTTPS包也类似,在Help->SSL Proxying中下载证书,双击安装证书,并选择始终信任即可。

参考

超文本传输安全协议
图解HTTPS
HTTPS从原理到应用
那些证书相关的玩意儿
SSL/TLS协议运行机制的概述
SSL/TLS协议及Openssl工具的实现
openssl自签名证书生成与单双向验证
iOS 10 适配 ATS
iOS安全系列之一:HTTPS
iOS安全系列之二:HTTPS进阶

from https://www.jianshu.com/p/6b19adb84150
---------------------------
CA和证书,
安全协议(SSL/TLS),

OpenSSH

一、CA和证书

(一) PKI(Public Key Infrastructure) 公钥基础设施

  • 定义:支持公开密钥管理并能支持认证、加密、完整性和可追究性服务的基础设施
  • 主要组成部分:
    • 签证机构:CA (Certificate Authority)
    • 注册机构:RA (Registration Authority)
    • 证书吊销列表:CRL (Certificate Revocation List)
    • 证书存取库
  • X.509:定义了证书的结构以及认证协议标准
    • 内容:版本号、序列号、签名算法、颁发者、有效期限、主体名称、主体公钥、CRL分发点、扩展信息、发行者签名

(二)证书获取的方法:

  • 证书授权机构签发的证书:由CA签发申请者的公钥
    • 第1步:生成签名请求(csr)
    • 第2步:将csr发送给CA
    • 第3步:从CA处接受签名
  • 自签名的证书:自己签发自己的公钥

二、安全协议(SSL/TLS):

(一)协议历史、功能

  • 发展历程:
    • SSL(Secure Socket Layer):安全套接字
      • 由Netscape公司于1995年发布SSL 2.0
    • TLS(Transport Layer Security) 安全传输层协议1.1:
      • TLS 1.1:IETF(Internet工程任务组) 于2006年将其定义为国际标准RFC 4346
      • TLS 1.2:当前使用最广泛的标准,2008年发布
      • TLS 1.3:最新标准,2015年发布
  • 提供功能:机密性、认证、完整性、重放保护
  • 位于TCP/IP模型传输层之上,应用层之下

(二)协议工作原理

  • SSL/TLS协议是两阶段协议,分为握手阶段和应用阶段
    • 握手阶段(协商阶段)客户端和服务器端认证对方身份(依赖于PKI体系,利用数字证书进行身份认证),并协商通信中使用的安全参数、密码套件以及主密钥。后续通信使用的所有密钥都是通过MasterSecret生成。
    • 应用阶段:在握手阶段完成后进入,在应用阶段通信双方使用握手阶段协商好的密钥进行安全通信
  • 相关协议:
    • 握手阶段:Handshake, ChangeCipherSpec, Alert协议
    • 应用阶段:Record协议
  • HTTPS协议:就是“HTTP” 协议”和“SSL/TLS 协议”的组合。HTTP over SSL”或“HTTP over TLS”,对http协议的文本数据进行加密处理后,成为二进制形式传输

(三)OpenSSL

  • 开源项目:可以实现对称加密、公钥加密、秘钥管理等丰富功能
  • 对称加密:openssl enc工具实现
    • 帮助:man enc
    • 语法:
    // 加密
    openssl enc -e -des3 -a -salt -in testfile -out testfile.cipher
    // 解密
    openssl enc -d -des3 -a -salt -in testfile.cipher -out testfile
    
  • 公钥加密:openssl rsautl工具实现
    • 帮助:man rsautl
    • 语法:
    // 生成私钥
    openssl genrsa -out /PATH/TO/PRIVATEKEY.FILE NUM_BITS
    // 私钥需要谨慎保管,权限应设置为600
    // 执行umask 066,为避免umask设置影响今后操作,将umask和后续生成私钥命令用小括号括起
    // 例如以下命令(-des: 私钥添加口令)
    (umask077; openssl genrsa -out test.key -des 2048) 
    
    //从私钥中提取出公钥
    openssl rsa -in PRIVATEKEYFILE -pubout -out PUBLICKEYFILE
    //例如以下命令
    openssl rsa -in test.key -pubout -out test.key.pub
  • 单项加密:openssl dgst工具实现
    • 帮助:man dgst
    • 语法:
    openssl dgst -md5 [-hex] /PATH/SOMEFILE     //-hex 默认设置为16进制显示
    openssl dgst -md5 testfile
    
  • 生成密码:openssl sslpasswd工具实现
    • 帮助:man sslpasswd
    • 语法:
    openssl passwd -1 -salt SALT(最多8位)  //-1指MD5加密
    openssl passwd -1 -salt centos
  • 生成随机数:openssl sslrand工具实现
    • 帮助:man sslrand
    • 帮助:
    openssl rand -base64|-hex NUM
    NUM: 表示字节数;-hex时,每个字符为十六进制,相当于4位二进制,出现的字符数为NUM*2

(四)OpenSSL实现创建CA并申请、管理证书

  • 配置文件
    • openssl的配置文件:/etc/pki/tls/openssl.cnf
      配置文件关键信息:
dir             = /etc/pki/CA          //存储目录
certs           = $dir/certs           //颁发的证书存储路径
crl_dir         = $dir/crl             //证书吊销列表存储路径
database        = $dir/index.txt       //数据库文件存储路径

new_certs_dir   = $dir/newcerts        //新证书存放路径,与证书存储路径中的内容相同,但名称不同

certificate     = $dir/cacert.pem      //CA自签发或由上级签发的证书路径,名称必须为"cacert.pem"
serial          = $dir/serial          //下一个签发证书的序号,一般从16位数字00开始
crlnumber       = $dir/crlnumber       //下一个证书吊销列表的序号,一般从16位数字00开始
                                  
crl             = $dir/crl.pem         //证书吊销列表的存放路径
private_key     = $dir/private/cakey.pem      //私钥的存放路径

countryName             = match        //国家信息必须匹配
stateOrProvinceName     = match        //州或省信息必须匹配
organizationName        = match        //域名信息必须匹配
organizationalUnitName  = optional     //部门名称
commonName              = supplied     //申请证书的主机名称
emailAddress            = optional     //邮箱
  • 申请信息的三种策略:匹配、支持和可选
    • 匹配:申请填写的信息跟CA设置信息必须一致
    • 支持:必须填写这项申请信息
    • 可选:可有可无
  • 第1步,创建私有CA,生成私钥
    // 创建所需要的文件
    touch /etc/pki/CA/index.txt      //生成证书索引数据库文件
    echo 01 > /etc/pki/CA/serial     //指定第一个颁发证书的序列号
    
    // CA生成私钥,注意名称必须为cakey.pem
    (umask066; openssl genrsa -out /etc/pki/CA/private/cakey.pem 2048)
    
  • 第2步,生成自签名证书
    openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -days 7300 -out /etc/pki/CA/cacert.pem
    // -new 生成新证书签署请求
    // -x509 专用于CA生成自签证书
    // -key 生成请求时用到的私钥文件
    // -days n 证书的有效期限
    // -out /PATH/TO/SOMECERTFILE: 证书的保存路径
    
  • 第3步,颁发证书,一般将私钥和CA签发的证书保存在应用的目录中
    // 1. 生成证书请求csr
    // 生成私钥
    (umask066; openssl genrsa -out /etc/pki/tls/private/test.key 2048)
    生成证书申请文件
    openssl req -new -key /etc/pki/tls/private/test.key -out etc/pki/tls/test.csr
    
    // 2. 将证书请求文件传输给CA
    
    // 3. CA签署证书,并将证书颁发给请求者
    openssl ca -in /tmp/test.csr -out /etc/pki/CA/certs/test.crt -days 365
    注意:默认国家,省,公司名称三项必须和CA一致
    
    // 4. 查看证书中的信息:
    openssl x509 -in /PATH/FROM/CERT_FILE -noout -text|issuer|subject|serial|dates
    // 查看指定编号的证书状态
    openssl ca -status SERIAL
    
  • 第4步,吊销证书
    // 1. 在客户端获取要吊销的证书的serial
    openssl x509 -in /PATH/FROM/CERT_FILE -noout -serial -subject
    
    // 2. 在CA上,根据客户提交的serial与subject信息,对比检验是否与index.txt文件中的信息一致,吊销证书
    openssl ca -revoke /etc/pki/CA/newcerts/SERIAL.pem
    // 指定第一个吊销证书的编号
    注意:第一次更新证书吊销列表前,才需要执行
    echo 01 > /etc/pki/CA/crlnumber
    
    // 3. 更新证书吊销列表
    openssl ca -gencrl -out /etc/pki/CA/crl/crl.pem
    // 查看crl文件:
    openssl crl -in /etc/pki/CA/crl/crl.pem -noout -text
    
  • 实验:建立根CA,子CA,并实现根CA签发自身证书、根CA给子CA签发证书、子CA给申请者签发证书,最后吊销子CA签发给申请者的证书,并生成证书吊销列表
    环境设置
    根CA的ip地址:192.168.136.230,命令提示符颜色:紫色
    子CA的ip地址:192.168.136.229,命令提示符颜色:黄色
    申请主机的ip地址:192.168.136.224,命令提示符颜色:蓝色
第1步:建立根CA,根CA签发自身证书(根CA上操作)
建立证书索引库文件index.txt,指定证书序列号
touch /etc/pki/CA/index.txt
echo 01 > /etc/pki/CA/serial
生成私钥文件cakey.pem,存储在/etc/pki/CA/private目录下
(umask 066; openssl genrsa -out /etc/pki/CA/private/cakey.pem -des3 2048)
自已签发自己的证书cacert.pem,存储在/etc/pki/CA目录下,过程中设置:countryName, stateOrProvinceName, organizationName, organizationalUnitName, commonName, emailAddress等信息,前三项一定要注意,之后签发的证书信息务必要与本次设置的信息相同
openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.pem -days 7300
第2步,建立子CA,子CA向根CA申请证书,根CA签发证书(子CA上操作)
建立证书索引库文件index.txt,指定证书序列号
touch /etc/pki/CA/index.txt
echo 01 > /etc/pki/CA/serial
生成私钥
(umak 066; openssl genrsa -out /etc/pki/CA/private/cakey.pem -des3 2048)
生成证书申请文件
openssl req -new -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.csr
将证书申请文件传送给根CA,根CA签发证书并将证书传送回子CA,存储至子CA的/etc/pki/CA目录下
scp /etc/pki/CA/cacert.csr 192.168.136.230:/tmp 发送证书申请文件至根CA,
openssl ca -in /tmp/cacert.csr -out /etc/pki/CA/certs/cacert.pem -days 3650
根CA签发证书(此命令在根CA上操作)
查看签发的证书内容,可以看到证书序列号按照/etc/pki/CA/serial文件中的01编号,根CA和子CA的关键信息相同(此命令在根CA上操作)
使用openssl x509 -in /etc/pki/CA/certs/cacert.pem -noout -text|issuer|suject|serial|dates命令查看证书信息,红框中可以看到时间期限确实为签发证书指定的约10年(-days 3650)(此命令在根CA上操作)

使用openssl ca -status 01命令,查看指定编号的证书状态(此命令在根CA上操作).

scp /etc/pki/CA/certs/cacert.pem 192.168.136.229:/etc/pki/CA/
发送签发的证书至子CA(此命令在根CA上操作)

第3步,申请主机向子CA发起证书签发申请,子CA签发证书(申请主机上操作)
生成密钥
(umask 066; openssl genrsa -out /etc/pki/tls/private/hello.key -des3 2048)
生成证书申请文件
openssl req -new -key /etc/pki/tls/private/hello.key -out /etc/pki/tls/hello.csr
将证书申请文件传送给子CA,子CA签发证书并将证书传送回申请主机,存储至申请主机的/etc/pki/tls目录下
scp /etc/pki/tls/hello.csr 192.168.136.229:/tmp 发送证书申请文件至子CA.
openssl ca -in /tmp/hello.csr -out /etc/pki/CA/certs/hello.crt -days 730
子CA签发证书(此命令在子CA上操作)
scp /etc/pki/CA/certs/hello.crt 192.168.136.224:/etc/pki/tls/
发送签发的证书至子CA(此命令在子CA上操作),
将根CA证书、子CA证书、申请主机证书都传至windows,可以在证书页面看到清晰的证书继承关系.
第4步,吊销子CA给申请主机的证书,创建证书吊销列表(子CA上操作)
环境设置:在子CA上再签发两个证书
修改/etc/pki/CA/index.txt.attr文件,内容改为"unique_subject = no",这样可以为相同证书申请签发多次证书
openssl ca -in /tmp/hello.csr -out /etc/pki/CA/certs/hello1.crt -days 300
openssl ca -in /tmp/hello.csr -out /etc/pki/CA/certs/hello2.crt -days 500
查看想要吊销证书的序列号,查看目前所有证书的状态,V表示可用状态
openssl x509 -in /etc/pki/CA/certs/hello1.crt -noout -serial -subject
openssl x509 -in /etc/pki/CA/certs/hello2.crt -noout -serial -subject
cat /etc/pki/CA/index.txt
``

吊销序列号为02和03的两个证书:
openssl ca -revoke /etc/pki/CA/newcerts/02.pem
openssl ca -revoke /etc/pki/CA/newcerts/03.pem
cat /etc/pki/CA/index.txt 查看索引数据库,发现被吊销的证书状态为R.

生成证书吊销列表
echo 01 > /etc/pki/CA/crlnumber 指定首个证书吊销列表的序列号
openssl ca -gencrl -out /etc/pki/CA/crl/crl.pem 生成证书吊销列表.
查看证书吊销列表内容
openssl crl -in /etc/pki/CA/crl/crl.pem -noout -text

三、OpenSSH

(一)SSH协议

  • ssh: secure shell,TCP连接,默认端口号22,安全的端口登录
  • 软件实现:OpenSSH, dropbear
  • 协议版本:当前使用ssh v2,基于DH算法做密钥交换,基于RSA或DSA实现身份认证
  • 登录认证方式:基于password和基于key两种方式

(二)OpenSSH

  • 基于C/S结构
    • client: ssh, scp, xshell, securecrt
    • server: sshd
  • ssh客户端:
    • 路径:/etc/ssh/ssh_config
    • 配置项:
      StrictHostKeyChecking 首次登录检查Key,默认为"ask"提示,设为"no"不提示
    • 语法:
      ssh [user@]host [COMMAND] 默认以当前本机登录用户名登录远程主机
      ssh [-l user] host [COMMAND] -l 指定用户登录远程主机
    选项:
    -p port:远程服务器监听的端口
    -b:指定连接的源IP
    -v:调试模式
    -C:压缩方式
    -X:支持x11转发
    -Y:支持信任x11转发
    -t:强制伪tty分配
    //通过ssh直连remoteserver1实现间接连接至remoteserver2
    ssh -t remoteserver1 ssh remoteserver2
    

(三)OpenSSH远程验证

  • openssh实现远程主机验证的方式:
    当用户远程连接ssh服务器时,会复制ssh服务器/etc/ssh/ssh_host*key.pub文件中的公钥到客户机的~./ssh/know_hosts中。下次连接时,会自动匹配相应私钥,不能匹配,将拒绝连接
  • ssh服务登录验证:基于用户/口令和基于密钥两种方式
    • 基于用户/口令登录
      • step 1 客户端发起ssh请求,服务器会把自己的公钥发送给用户
      • step 2 用户会根据服务器发来的公钥对密码进行加密
      • step 3 加密后的信息回传给服务器,服务器用自己的私钥解密,如果密码正确,则用户登录成功
    • 基于密钥登录
      • step 1 首先在客户端生成一对密钥
      • step 2 并将客户端的公钥拷贝到服务端
      • step 3 当客户端再次发送一个连接请求,包括ip, 用户名
      • step 4 服务端得到客户端的请求后,会到authorized_keys中查找,如果有响应的IP和用户,就会随机生成一个字符串,例如:acdf
      • step 5 服务端使用客户端拷贝过来的公钥进行加密,然后发送给客户端
      • step 6 得到服务端发来的消息后,客户端会使用私钥进行解密,然后将解密后的字符串发送给服务端
      • step 7 服务端接受到客户端发来的字符串后,跟之前的字符串进行对比,如果一致,就允许免密码登录
    • 实现基于密钥登录
      • 在客户端生成密钥对,-P '':私钥不设置密码
        ssh-keygen -t rsa [-P ''] [-f "~/.ssh/id_rsa"]
      • 把公钥文件传输至远程服务器对应用户的家目录
        ssh-copy-id [-i [identity_file]] [user@]host
      • 修改私钥的密码
        ssh-keygen -p
      • 使用验证代理,只需要输入一次密码,之后所有的ssh连接输入私钥密码的工作由代理完成。bash进程结束,代理工作结束;下次登录时,重新启动代理。
        ssh-agent agent 启用代理
        ssh-add 密码添加给代理

(四)加密文件传输工具:scp, rsysc, sftp, pssh

(1)scp工具
  • 来源于openssh-clients软件包
  • scp遇到相同文件直接覆盖操作
  • 语法:
    scp [options] SRC... DEST/
    scp [options] [user@]host:/sourcefile /destpath:将远程主机文件复制到本地
    scp [options] /sourcefile [user@]host:/destpath:将本地文件复制到远程主机
  • 常用选项:
    -C: 压缩数据流
    -r: 递归复制
    -p: 保持原文件的属性信息
    -q: 静默模式
    -P PORT: 指明remote host的监听端口
(2)rsync工具
  • 基于ssh和rsh服务实现高效率的远程系统之间复制文件
  • 使用安全的shell连接做为传输方式
  • 比scp更快,只复制不同的文件
  • 语法:
    rsync -av /etc server1:/tmp:复制目录和目录下文件
    rsync -av /etc/ server1:/tmp:只复制目录下文件
  • 选项:
    -n 模拟复制过程
    -v 显示详细过程
    -r 递归复制目录树
    -p 保留权限
    -t 保留时间戳
    -g 保留组信息
    -o 保留所有者信息
    -l 将软链接文件本身进行复制(默认)
    -L 将软链接文件指向的文件复制
    -a 存档,相当于–rlptgoD,但不保留ACL(-A) 和SELinux属性(-X)
(3)sftp工具
  • 交互式文件传输工具
  • 用法和传统的ftp工具相似
  • 利用ssh服务实现安全的文件上传和下载
  • 使用ls cd mkdir rmdir pwd get put等指令,可用?help获取帮助信息
(4)pssh工具
  • pssh是一个python编写可以在多台服务器上执行命令的工具,也可实现文件复制
  • 选项如下:
    --version:查看版本
    -h:主机文件列表,内容格式"[user@]host[:port]"
    -H:主机字符串,内容格式"[user@]host[:port]"
    -l:登录使用的用户名
    -o:输出的文件目录
    -O:SSH的选项
    -v:详细模式
    -A:手动输入密码模式
    -x:额外的命令行参数使用空白符号,引号,反斜线处理
    -X:额外的命令行参数,单个参数模式,同-x
    -i:每个服务器内部处理信息输出
    -P:打印出服务器返回信息

(五)SSH端口转发(又名“隧道”):

(1)SSH 端口转发的功能
  • SSH端口转发:SSH将其他TCP 端口的网络数据通过SSH 链接来转发,并且自动提供了相应的加密及解密服务
  • SSH端口转发又名隧道(tunneling),SSH为其他TCP协议提供了一个安全的传输通道。
  • 功能:
    • 加密SSH Client 端至SSH Server 端之间的通讯数据
    • 突破防火墙的限制完成一些之前无法建立的TCP 连接
(2)SSH本地转发
  • 语法:
    ssh -L local_port:remote_host:remote_host_port ssh_server
    local_port:本地端口(防火墙外)
    remote_host:远程主机IP(防火墙内)
    remote_host_port:远程主机不安全的TCP协议端口(防火墙内)
    ssh_server:充当跳板机的ssh服务器IP(防火墙内)
  • 选项:
    -f 后台启用
    -N 不打开远程shell,处于等待状态
    -g 启用网关功能
  • 示例:
    • ssh -L 2009:telnetsrv:23 -Nf sshsrv
      建立从本机到telnet服务器23端口的连接,监听本机2009端口,以sshsrv服务器为跳板
    • telnet 127.0.0.1 2009
      当访问本机的2009的端口时,被加密后转发到sshsrv的ssh服务,再解密被转发至telnetsrv的23端口
    • 信息在端口间的流向:
      data <<==>> local_host:2009 <<==>> local_host:XXXXX <<==>> ssh_srv:22 <<==>> ssh_srv:YYYYY <<==>> telnet_srv:23
  • 实验:建立SSH本地转发
    建立从本机192.168.136.230到telnet服务器192.168.136.224的连接,中间将ssh服务器192.168.136.229作为跳板,本地转发端口2009
    ssh -L 2009:192.168.136.224:23 -Nf 192.168.136.229 本地建立连接
    telnet 127.0.0.1 2009 本地转发连接远程telnet服务器.
    本地主机端口连接情况:本机连接至跳板机的ssh服务22端口.
    跳板机端口连接情况:跳板机一方面与本机以ssh服务22端口连接,一方面与远程服务器以telnet服务23端口连接.
    远程telnet服务器端口连接情况:跳板机连接至远程服务器的telnet服务23端口.
    数据流向为:data <<==>> 127.0.0.1:2009 <<==>> 192.168.136.230:56160 <<==>> 192.168.136.229:22 <<==>> 192.168.136.229:51488 <<==>> 192.168.136.224:23
(3)SSH远程转发
  • 语法:
    ssh -R ssh_server_port:remote_host:remote_host_port ssh_server
    ssh_server_port:(防火墙外)
    remote_host_port:(防火墙内)
    remote_host_port:(防火墙内)
    ssh_server:(防火墙外)
  • 示例:
    • ssh -R 2010:telnetsrv:23 -Nf sshsrv
      建立从ssh服务器到telnet服务器23端口的连接,监听ssh服务器2010端口,以ssh客户端为跳板
    • telnet sshsrv 2010
      当访问本机的2010端口时,将加密信息通过ssh服务转发请求到本机ssh客户端,再由本机解密后转发到telnetsrv的23端口
    • 信息在端口间的流向:
      Data <==> ssh_srv:2010 <==> ssh_srv:22 <==> local_host:XXXXX <==> local_host:YYYYY <==> telnet_srv:23
  • 实验:建立SSH远程转发
    建立从ssh服务器192.168.136.230到telnet服务器192.167.136.224的连接,中间将本机192.168.136.229作为跳板,远程转发端口2010
    ssh -R 2010:192.168.136.224:23 -Nf 192.168.136.230 本机建立连接.
    telnet 127.0.0.1 2010 远程ssh服务器连接远程telnet服务器.
    ssh服务器端口连接情况:ssh服务器的22端口与主机相连.
    主机端口连接情况:一方面作为客户机与防火墙外的ssh服务器连接,另一方面与防火墙内的telnet服务器的23端口连接.
    telnet服务器端口连接情况:telnet服务器的23端口与主机相连.
(4)SSH端口转发
  • 当用浏览器访问internet时,本机的1080端口做为代理服务器,浏览器的访问请求被转发到ssh_server上,由ssh_server替之访问internet
  • 示例:
    • ssh -D 1080 root@sshserver
      建立本地1080端口至ssh_server的ssh连接
    • 在浏览器设置代理本地代理:ip:127.0.0.1 port:1080
  • 实验:建立SSH端口转发
    通过本机(192.168.136.224)1080端口转发请求至192.168.136.230的ssh服务器,由ssh服务器访问192.168.136.229的httpd服务

(六)SSH的X协议转发:

  • X协议:C/S结构,Client程序向Server发出请求,Server响应请求并展现相关图形界面
  • 所有的图形应用程序都是X客户程序
    • 能够通过TCP/IP连接远程X服务器
    • 数据没有加密机制,可以通过ssh连接隧道安全传输
  • OpenSSH的实现:
    ssh -X user@remotehost COMMAND
from:https://www.jianshu.com/p/ca0f4a0fb18c
-----

https://github.com/james-proxy/james , It is an open-source alternative to the popular developer tool Charles

No comments:

Post a Comment