nginx ssl设置详解

SSL 协议

SSLv2是不安全的,绝对不能用,SSLv3 能不用则不用,正常情况下用不到的,推荐使用 TLSv1 TLSv1.1 TLSv1.2,附配置代码:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

加密算法

RC4不要用,再就是 OpenSSL 记得更新到最新版,可以避免很多麻烦。别的也没什么了,附代码:

ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

ssl_prefer_server_ciphers on;

ECDHE+AESGCM 加密是首选的。它们是 TLS 1.2 加密算法,现在还没有广泛支持。当然也没有破解的方案。
PFS 加密套件好一些,首选 ECDHE,然后是 DHE
AES 128 要好于 AES 256AES 256 会造成更大的性能消耗,但是带来的安全提升是有限的。反之还能承受更大压力。
在向后兼容的加密套件里面,AES 要优于 3DES。在 TLS 1.1及其以上,减轻了针对 AES 的野兽攻击(BEAST)的威胁,而在 TLS 1.0上则难以实现该攻击。在非向后兼容的加密套件里面,不支持 3DES
RC4 整个不支持了。3DES 用来向后兼容。
强制丢弃的算法
aNULL 包含了非验证的 Diffie-Hellman 密钥交换,这会受到中间人(MITM)攻击
eNULL 包含了无加密的算法(明文)
EXPORT 是老旧的弱加密算法,是被美国法律标示为可出口的
RC4 包含使用了已弃用的 ARCFOUR 的加密算法
DES 包含使用了弃用的数据加密标准(DES)的加密算法
SSLv2 包含了定义在旧版本 SSL 标准中的所有算法,现已弃用
MD5 包含了使用已弃用的 MD5 的所有算法
但是 ECC 证书的部署不大一样,加密套件和 RSA 不一样,用错之后会影响向前安全性(Forward secrecy)。
加密套件应该这么改:

ssl_ciphers "EECDH+CHACHA20 EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";

而根据https://cipherli.st/的推荐,可以进一步改为:

ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";

前向安全性(Forward Secrecy)

首先 Nginx 配置上如下代码:

ssl_dhparam /your/path/to/dhparam.pem;

pem 文件是这样生成的:

openssl dhparam -out dhparam.pem 4096

然后会显示:

This is going to take a long time  
.......+...........................+............................+............................+............++*++*++*

这真的会”take a long time”.但根据每台机器的性能不同而花费的时间不同.

dhparam 算法是在 2^4096 个数字中找出两个质数,所以需要的时间挺长。….. 意思是有可能的质数,+ 是正在测试的质数,* 是已经找到的质数。

前向安全性(Forward Secrecy)的概念很简单:客户端和服务器协商一个永不重用的密钥,并在会话结束时销毁它。服务器上的 RSA 私钥用于客户端和服务器之间的 Diffie-Hellman 密钥交换签名。从 Diffie-Hellman 握手中获取的预主密钥会用于之后的编码。因为预主密钥是特定于客户端和服务器之间建立的某个连接,并且只用在一个限定的时间内,所以称作短暂模式(Ephemeral)。
如果使用前向安全机制,攻击者取得了一个服务器的私钥,他是不能解码之前的通讯信息的。这个私钥仅用于 Diffie Hellman 握手签名,并不会泄露预主密钥。Diffie Hellman 算法会确保预主密钥绝不会离开客户端和服务器,而且不能被中间人攻击所拦截。
所有版本的 nginx 都依赖于 OpenSSL 给 Diffie-Hellman 的输入参数。如果不特别声明,将使用 OpenSSL 的默认设置,1024 位密钥。这绝壁是不安全的,因为我们正在使用 2048 位证书,所以要有一个更强大的 DH

HTTP 严格传输安全(HSTS)(HTTP Strict Transport Security)

HTTP严格传输安全(英语:HTTP Strict Transport Security,缩写:HSTS)是一套由互联网工程任务组发布的互联网安全策略机制。网站可以选择使用HSTS策略,来让浏览器强制使用HTTPS与网站进行通信,以减少会话劫持风险。
HSTS的作用是强制客户端(如浏览器)使用HTTPS与服务器创建连接。服务器开启HSTS的方法是,当客户端通过HTTPS发出请求时,在服务器返回的超文本传输协议响应头中包含Strict-Transport-Security字段。非加密传输时设置的HSTS字段无效。

add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";

includeSubDomains是可选的,用来指定是否作用于子域名。支持HSTS的浏览器遇到这个响应头,会把当前网站加入HSTS列表,然后在max-age指定的秒数内,当前网站所有请求都会被重定向为https。即使用户主动输入http://或者不输入协议部分,都将重定向到https://地址。

X-Frame-Options 响应头

X-Frame-Options HTTP 响应头是用来给浏览器指示允许一个页面可否在 <frame>, <iframe> 或者 <object> 中展现的标记。网站可以使用此功能,来确保自己网站的内容没有被嵌到别人的网站中去,也从而避免了点击劫持 (clickjacking) 的攻击。
X-Frame-Options 有三个值:
DENY:表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。
SAMEORIGIN:表示该页面可以在相同域名页面的 frame 中展示。
ALLOW-FROM uri:表示该页面可以在指定来源的 frame 中展示。
换一句话说,如果设置为 DENY,不光在别人的网站 frame 嵌入时会无法加载,在同域名页面中同样会无法加载。另一方面,如果设置为 SAMEORIGIN,那么页面就可以在同域名页面的 frame 中嵌套。

X-Content-Type-Options 响应头

互联网上的资源有各种类型,通常浏览器会根据响应头的Content-Type字段来分辨它们的类型。例如:”text/html”代表html文档,”image/png”是PNG图片,”text/css”是CSS样式文档。然而,有些资源的Content-Type是错的或者未定义。这时,某些浏览器会启用MIME-sniffing来猜测该资源的类型,解析内容并执行。
例如,我们即使给一个html文档指定Content-Type为”text/plain”,在IE8-中这个文档依然会被当做html来解析。利用浏览器的这个特性,攻击者甚至可以让原本应该解析为图片的请求被解析为JavaScript。通过下面这个响应头可以禁用浏览器的类型猜测行为:

add_header X-Content-Type-Options nosniff;

这个响应头的值只能是nosniff,可用于IE8+和Chrome。

配置 OCSP 装订

ssl_stapling on;  
ssl_stapling_verify on;  
ssl_trusted_certificate /you/path/to/domain.chain.pem;  
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 10s;

domain.chain.pem 里面是域名证书到 ROOT 证书的一个链。
连接到一个服务器时,客户端应该使用证书吊销列表(CRL)或在线证书状态协议(OCSP)记录来校验服务器证书的有效性。CRL 存在一个问题,它已经增长的太快,永远也下载不完。
OCSP 更轻量一些,只需发一个请求。但是副作用是访问一个站点时必须对第三方 OCSP 响应服务器发起 OCSP 请求,这就增加了延迟带来的潜在隐患。事实上,CA 所运营的 OCSP 响应服务器非常不可靠,浏览器如果不能及时收到答复,就会静默失败。攻击者通过 DDoS 攻击一个 OCSP 响应服务器可以禁用其校验功能,这样就降低了安全性。
解决方法是允许服务器在 TLS 握手中发送缓存的 OCSP 记录,以绕开 OCSP 响应服务器。这个机制减少了客户端和 OCSP 响应服务器之间的通讯,称作 OCSP 装订。
客户端会在它的 CLIENT HELLO 中告知其支持 status_request TLS 扩展,服务器仅在客户端请求它的时候才发送缓存的 OCSP 响应。
大多数服务器最长会缓存 OCSP 48 小时。服务器会按照常规的间隔连接到 CA 的 OCSP 响应服务器来获取刷新的 OCSP 记录。OCSP 响应服务器的位置可以从签名的证书中 Authority Information Access 字段中获得。

nginx里边SSL的完整配置

    ssl on;
    #文件位置
    ssl_certificate /path/to/pem;
    ssl_certificate_key /path/to/key;
    ssl_dhparam /path/to/dhparams.pem;
    #会话进程设置
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_session_timeout 5m;
    #加密套件设置
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
    ssl_prefer_server_ciphers on;
    ssl_ecdh_curve secp384r1;
    #OCSP配置
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 216.69.185.17 208.109.255.17 valid=300s;
    resolver_timeout 5s;
    #HTTP安全配置
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;

文章拼凑来源:
https://cipherli.st/
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/X-Frame-Options
https://okwoo.com/open-the-hsts-http-strict-transport-security-the-importance-of
https://www.pupboss.com/nginx-add-ssl/
https://imququ.com/post/web-security-and-response-header.html

基于OpenSSL自建CA和颁发SSL证书

关于SSL/TLS介绍见文章 SSL/TLS原理详解
关于证书授权中心CA以及数字证书等概念,请移步 OpenSSL 与 SSL 数字证书概念
openssl是一个开源程序的套件、这个套件有三个部分组成:一是libcryto,这是一个具有通用功能的加密库,里面实现了众多的加密库;二是libssl,这个是实现ssl机制的,它是用于实现TLS/SSL的功能;三是openssl,是个多功能命令行工具,它可以实现加密解密,甚至还可以当CA来用,可以让你创建证书、吊销证书。
默认情况ubuntu和CentOS上都已安装好openssl。CentOS 6.x 上有关ssl证书的目录结构:

/etc/pki/CA/
            newcerts    存放CA签署(颁发)过的数字证书(证书备份目录)
            private     用于存放CA的私钥
            crl         吊销的证书

/etc/pki/tls/
             cert.pem    软链接到certs/ca-bundle.crt
             certs/      该服务器上的证书存放目录,可以房子自己的证书和内置证书
                   ca-bundle.crt    内置信任的证书
             private    证书密钥存放目录
             openssl.cnf    openssl的CA主配置文件

1. 颁发证书
1.1 修改CA的一些配置文件
CA要给别人颁发证书,首先自己得有一个作为根证书,我们得在一切工作之前修改好CA的配置文件、序列号、索引等等。

vim /etc/pki/tls/openssl.cnf:
...
[ CA_default ]

dir             = /etc/pki/CA           # Where everything is kept
certs           = $dir/certs            # Where the issued certs are kept
crl_dir         = $dir/crl              # Where the issued crl are kept
database        = $dir/index.txt        # database index file.
#unique_subject = no                    # Set to 'no' to allow creation of
                                        # several ctificates with same subject.
new_certs_dir   = $dir/newcerts         # default place for new certs.

certificate     = $dir/cacert.pem       # The CA certificate
serial          = $dir/serial           # The current serial number
crlnumber       = $dir/crlnumber        # the current crl number
                                        # must be commented out to leave a V1 CRL
crl             = $dir/crl.pem          # The current CRL
private_key     = $dir/private/cakey.pem # The private key
RANDFILE        = $dir/private/.rand    # private random number file
...
default_days    = 3650                  # how long to certify for
...
# For the CA policy
[ policy_match ]
countryName             = match
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
...
[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = CN
countryName_min                 = 2
countryName_max                 = 2

stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = GD
...
[ req_distinguished_name ] 部分主要是颁证时一些默认的值,可以不动

一定要注意[ policy_match ]中的设定的匹配规则,是有可能因为证书使用的工具不一样,导致即使设置了csr中看起来有相同的countryName,stateOrProvinceName等,但在最终生成证书时依然报错:

Using configuration from /usr/lib/ssl/openssl.cnf
Check that the request matches the signature
Signature ok
The stateOrProvinceName field needed to be the same in the
CA certificate (GuangDong) and the request (GuangDong)

在CA目录下创建两个初始文件:

# touch index.txt serial
# echo 01 > serial

1.2 生成根密钥

# cd /etc/pki/CA/
# openssl genrsa -out private/cakey.pem 2048

为了安全起见,修改cakey.pem私钥文件权限为600或400,也可以使用子shell生成( umask 077; openssl genrsa -out private/cakey.pem 2048 ),下面不再重复。
1.3 生成根证书
使用req命令生成自签证书:

# openssl req -new -x509 -key private/cakey.pem -out cacert.pem

会提示输入一些内容,因为是私有的,所以可以随便输入(之前修改的openssl.cnf会在这里呈现),最好记住能与后面保持一致。上面的自签证书cacert.pem应该生成在/etc/pki/CA下。
以上都是在CA服务器上做的操作,而且只需进行一次,现在转到nginx服务器上执行:

# cd /etc/nginx/ssl
# openssl genrsa -out nginx.key 2048

这里测试的时候CA中心与要申请证书的服务器是同一个。
1.4 为我们的nginx web服务器生成ssl密钥
以上都是在CA服务器上做的操作,而且只需进行一次,现在转到nginx服务器上执行:

# cd /etc/nginx/ssl
# openssl genrsa -out nginx.key 2048

这里测试的时候CA中心与要申请证书的服务器是同一个。
1.5 为nginx生成证书签署请求

# openssl req -new -key nginx.key -out nginx.csr
...
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:GD
Locality Name (eg, city) []:SZ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:COMPANY
Organizational Unit Name (eg, section) []:IT_SECTION
Common Name (e.g. server FQDN or YOUR name) []:your.domain.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
同样会提示输入一些内容,其它随便,除了<code>Commone Name</code>一定要是你要授予证书的服务器域名或主机名,<code>challenge password</code>不填。
<strong>1.6 私有CA根据请求来签署证书</strong>
接下来要把上一步生成的证书请求csr文件,发到CA服务器上,在CA上执行:

# openssl ca -in nginx.csr -out nginx.crt
另外在极少数情况下,上面的命令生成的证书不能识别,试试下面的命令:
# openssl x509 -req -in server.csr -CA /etc/pki/CA/cacert.pem -CAkey /etc/pki/CA/private/cakey.pem -CAcreateserial -out server.crt

上面签发过程其实默认使用了-cert cacert.pem -keyfile cakey.pem,这两个文件就是前两步生成的位于/etc/pki/CA下的根密钥和根证书。将生成的crt证书发回nginx服务器使用。
到此我们已经拥有了建立ssl安全连接所需要的所有文件,并且服务器的crt和key都位于配置的目录下,剩下的是如何使用证书的问题。

2. 使用ssl证书

原文链接地址: http://seanlook.com/2015/01/18/openssl-self-sign-ca/

OpenSSL 与 SSL 数字证书概念

首先简单区分一下HTTPS、SSL、OpenSSL三者的关系:
SSL是在客户端和服务器之间建立一条SSL安全通道的安全协议,而OpenSSL是TLS/SSL协议的开源实现,提供开发库和命令行程序。常说的HTTPS是HTTP的加密版,底层使用的加密协议是SSL。
1. PKI、CA与证书
PKI 就是 Public Key Infrastructure 的缩写,翻译过来就是公开密钥基础设施。它是利用公开密钥技术所构建的,解决网络安全问题的,普遍适用的一种基础设施;是一种遵循既定标准的密钥管理平台,它能够为所有网络应用提供加密和数字签名等密码服务及所必需的密钥和证书管理体系。
PKI既不是一个协议,也不是一个软件,它是一个标准,在这个标准之下发展出的为了实现安全基础服务目的的技术统称为PKI。可以说CA(认证中心)是PKI的核心,而数字证书是PKI的最基本元素,还有如apache等服务器、浏览器等客户端、银行等应用,都是pki的组件。这篇文章可以帮助理解:PKI/CA 技术的介绍 。
1.1 CA
为保证用户之间在网上传递信息的安全性、真实性、可靠性、完整性和不可抵赖性CA 机构,又称为证书认证中心 (Certificate Authority) 中心,是一个负责发放和管理数字证书的第三方权威机构,它负责管理PKI结构下的所有用户(包括各种应用程序)的证书,把用户的公钥和用户的其他信息捆绑在一起,在网上验证用户的身份。CA机构的数字签名使得攻击者不能伪造和篡改证书。
认证中心主要有以下5个功能:
1) 证书的颁发:接收、验证用户(包括下级认证中心和最终用户)的数字证书的申请。可以受理或拒绝
2) 证书的更新:认证中心可以定期更新所有用户的证书,或者根据用户的请求来更新用户的证书
3) 证书的查询:查询当前用户证书申请处理过程;查询用户证书的颁发信息,这类查询由目录服务器ldap来完成
4) 证书的作废:由于用户私钥泄密等原因,需要向认证中心提出证书作废的请求;证书已经过了有效期,认证中心自动将该证书作废。认证中心通过维护证书作废列表 (Certificate Revocation List,CRL) 来完成上述功能。
5) 证书的归档:证书具有一定的有效期,证书过了有效期之后就将作废,但是我们不能将作废的证书简单地丢弃,因为有时我们可能需要验证以前的某个交易过程中产生的数字签名,这时我们就需要查询作废的证书。
1.2 Certificate
1.2.1 X.509标准
“SSL证书”这个词是一个相对较大的概念,整个PKI体系中有很多SSL证书格式标准。PKI的标准规定了PKI的设计、实施和运营,规定了PKI各种角色的”游戏规则”,提供数据语法和语义的共同约定。x.509是PKI中最重要的标准,它定义了公钥证书的基本结构,可以说PKI是在X.509标准基础上发展起来的:
 SSL公钥证书
 证书废除列表CRL(Certificate revocation lists 证书黑名单)
参考 http://en.wikipedia.org/wiki/X.509
1.2.2 ssl公钥证书格式

1. 证书版本号(VERSION)
版本号指明X.509证书的格式版本,现在的值可以为:
    1) 0: V1
    2) 1: V2
    3) 2: V3
也为将来的版本进行了预定义

2. 证书序列号(SERIAL NUMBER)
序列号指定由CA分配给证书的唯一的"数字型标识符"。当证书被取消时,实际上是将此证书的序列号放入由CA签发的CRL中,
这也是序列号唯一的原因。

3. 签名算法标识符(SIGNATURE ALGORITHM)
签名算法标识用来指定由CA签发证书时所使用的"签名算法"。算法标识符用来指定CA签发证书时所使用的:
    1) 公开密钥算法
    2) HASH算法
EXAMPLE: SHA256WITHRSAENCRYPTION
须向国际知名标准组织(如ISO)注册

4. 签发机构名(ISSUER)
此域用来标识签发证书的CA的X.500 DN(DN-DISTINGUISHED NAME)名字。包括:
    1) 国家(C)
    2) 省市(ST)
    3) 地区(L)
    4) 组织机构(O)
    5) 单位部门(OU)
    6) 通用名(CN)
    7) 邮箱地址

5. 有效期(VALIDITY)
指定证书的有效期,包括:
    1) 证书开始生效的日期时间
    2) 证书失效的日期和时间
每次使用证书时,需要检查证书是否在有效期内。

6. 证书用户名(SUBJECT)
指定证书持有者的X.500唯一名字。包括:
    1) 国家(C)
    2) 省市(ST)
    3) 地区(L)
    4) 组织机构(O)
    5) 单位部门(OU)
    6) 通用名(CN)
    7) 邮箱地址

7. 证书持有者公开密钥信息(SUBJECT PUBLIC KEY INFO)
证书持有者公开密钥信息域包含两个重要信息:
    1) 证书持有者的公开密钥的值
    2) 公开密钥使用的算法标识符。此标识符包含公开密钥算法和HASH算法。
8. 扩展项(EXTENSION)
X.509 V3证书是在V2的基础上一标准形式或普通形式增加了扩展项,以使证书能够附带额外信息。标准扩展是指
由X.509 V3版本定义的对V2版本增加的具有广泛应用前景的扩展项,任何人都可以向一些权威机构,如ISO,来
注册一些其他扩展,如果这些扩展项应用广泛,也许以后会成为标准扩展项。

9. 签发者唯一标识符(ISSUER UNIQUE IDENTIFIER)
签发者唯一标识符在第2版加入证书定义中。此域用在当同一个X.500名字用于多个认证机构时,用一比特字符串
来唯一标识签发者的X.500名字。可选。

10. 证书持有者唯一标识符(SUBJECT UNIQUE IDENTIFIER)
持有证书者唯一标识符在第2版的标准中加入X.509证书定义。此域用在当同一个X.500名字用于多个证书持有者时,
用一比特字符串来唯一标识证书持有者的X.500名字。可选。

11. 签名算法(SIGNATURE ALGORITHM)
证书签发机构对证书上述内容的签名算法
EXAMPLE: SHA256WITHRSAENCRYPTION

12. 签名值(ISSUER'S SIGNATURE)
证书签发机构对证书上述内容的签名值

example:

CERTIFICATE:
    DATA:
        VERSION: 3 (0X2)
        SERIAL NUMBER: 9 (0X9)
    SIGNATURE ALGORITHM: SHA256WITHRSAENCRYPTION
        ISSUER: C=CN, ST=GUANGDONG, L=SHENZHEN, O=COMPANY TECHNOLOGIES CO., LTD, OU=IT_SECTION, CN=registry.example.com.net/emailAddress=zhouxiao@example.com.net
        VALIDITY
            NOT BEFORE: FEB 11 06:04:56 2015 GMT
            NOT AFTER : FEB  8 06:04:56 2025 GMT
        SUBJECT: C=CN, ST=GUANGDONG, L=SHENZHEN, O=TP-LINK CO.,LTD., OU=NETWORK MANAGEMENT, CN=172.31.1.210
        SUBJECT PUBLIC KEY INFO:
            PUBLIC KEY ALGORITHM: RSAENCRYPTION
                PUBLIC-KEY: (2048 BIT)
                MODULUS:
                    00:A4:B0:DD:EB:C1:CF:5D:47:61:A6:EA:EF:8B:AA:
                    4B:F0:B4:2C:D8:96:C7:7C:AC:FA:C7:35:88:53:D0:
                    ...
                    8A:76:DC:8F:8C:44:C8:0B:3C:36:88:5F:01:F0:44:
                    4E:81:E6:7A:2B:FF:BA:DA:33:A5:27:11:C6:F0:08:
                    6E:F3
                EXPONENT: 65537 (0X10001)
        X509V3 EXTENSIONS:
            X509V3 BASIC CONSTRAINTS: 
                CA:FALSE
            NETSCAPE COMMENT: 
                OPENSSL GENERATED CERTIFICATE
            X509V3 SUBJECT KEY IDENTIFIER: 
                07:C6:87:B7:C1:1E:28:E8:96:3F:EB:40:1E:82:41:45:CA:81:B6:3D
            X509V3 AUTHORITY KEY IDENTIFIER: 
                KEYID:A4:C2:14:6A:39:D1:95:1E:BD:DF:3B:92:4A:5C:12:42:1B:BC:53:B8

    SIGNATURE ALGORITHM: SHA256WITHRSAENCRYPTION
         0C:C6:81:70:CD:0A:2D:94:4F:CB:A4:1D:EF:9E:8E:E4:73:AE:
         50:62:A8:9C:64:EF:56:0F:41:FE:6B:B4:D3:07:37:39:2C:ED:
         ...
         6F:62:61:B8:03:D7:97:31:AB:05:44:20:07:65:8B:AD:E2:CC:
         AD:65:73:F6:82:0F:9E:65:D0:AE:B7:1E:FD:9F:C1:D7:41:6C:
         0F:06:95:EE
-----BEGIN CERTIFICATE-----
MIIEMDCCAXIGAWIBAGIBCTANBGKQHKIG9W0BAQSFADCBTTELMAKGA1UEBHMCQ04X
EJAQBGNVBAGMCUD1YW5NRG9UZZERMA8GA1UEBWWIU2HLBLPOZW4XJJAKBGNVBAOM
...
UJWWRAR6PPZUSO95WUS93HSNML2ZFZ63DS4LCW9IYBGD15CXQWVEIADLI63IZK1L
C/ACD55L0K63HV2FWDDBBA8GLE4=
-----END CERTIFICATE-----

2. 附:数据加密的基础知识
 对称密钥加密
对称密钥加密(一个密钥),也叫做共享密钥加密或机密密钥加密,使用发件人和收件人共同拥有的单个密钥。这种密钥既用于加密,也用于解密,叫做机密密钥。对称密钥加密是加密大量数据的一种行之有效的方法。
对称密钥加密有许多种算法如DES,RC4,IDEA等,但所有这些算法都有一个共同的目的:以可还原的方式将明文 (未加密的数据转换为暗文。暗文使用加密密钥编码,对于没有解密密钥的任何人来说它都是没有意义的。由于对称密钥加密在加密和解密时使用相同的密钥,所以这种加密过程的安全性取决于是否有未经授权的人获得了对称密钥。
衡量对称算法优劣的主要尺度是其密钥的长度。密钥越长,在找到解密数据所需的正确密钥之前必须测试的密钥数量就越多。需要测试的密钥越多,破解这种算法就越困难。
 公钥加密
公钥加密使用两个密钥:一个公钥和一个私钥,这两个密钥在数学上是相关的。为了与对称密钥加密相对照,公钥加密有时也叫做不对称密钥加密。在公钥加密中,公钥可在通信双方之间公开传递,或在公用储备库中发布,但相关的私钥是保密的。只有使用私钥才能解密用公钥加密的数据。使用私钥加密的数据只能用公钥解密。下图中,发件人拥有收件人的公钥,并用它加密了一封邮件,但只有收件人掌握解密该邮件的有关私钥。

公钥算法的主要局限在于,这种加密形式的速度相对较低。实际上,通常仅在关键时刻才使用公钥算法,如在实体之间交换对称密钥时,或者在签署一封邮件的散列时(散列是通过应用一种单向数学函数获得的一个定长结果,对于数据而言,叫做散列算法)。将公钥加密与其它加密形式(如对称密钥加密)结合使用,可以优化性能,如数字签名和密钥交换。
常用公钥算法:
RSA:适用于数字签名和密钥交换。 是目前应用最广泛的公钥加密算法,特别适用于通过 Internet 传送的数据,RSA算法以它的三位发明者的名字命名。
DSA:仅适用于数字签名。 数字签名算法 (Digital Signature Algorithm, DSA) 由美国国家安全署 (United States National Security Agency, NSA) 发明,已作为数字签名的标准。DSA 算法的安全性取决于自计算离散算法的困难。这种算法,不适用于数据加密。
Diffie-Hellman:仅适用于密钥交换。 Diffie-Hellman 是发明的第一个公钥算法,以其发明者 Whitfield Diffie 和 Martin Hellman 的名字命名。Diffie-Hellman 算法的安全性取决于在一个有限字段中计算离散算法的困难。
单向散列算法:
散列,也称为散列值或消息摘要 ,是一种与基于密钥(对称密钥或公钥)的加密不同的数据转换类型。散列就是通过把一个叫做散列算法的单向数学函数应用于数据,将任意长度的一块数据转换为一个定长的、不可逆转的数字,其长度通常在128~256位之间。所产生的散列值的长度应足够长,因此使找到两块具有相同散列值的数据的机会很少。如发件人生成邮件的散列值并加密它,然后将它与邮件本身一起发送。而收件人同时解密邮件和散列值,并由接收到的邮件产生另外一个散列值,然后将两个散列值进行比较。如果两者相同,邮件极有可能在传输期间没有发生任何改变。
下面是几个常用的散列函数:
MD5:是RSA数据安全公司开发的一种单向散列算法,MD5被广泛使用,可以用来把不同长度的数据块进行暗码运算成一个128位的数值。
SHA-1:与 DSA 公钥算法相似,安全散列算法1(SHA-1)也是由 NSA 设计的,并由 NIST 将其收录到 FIPS 中,作为散列数据的标准。它可产生一个 160 位的散列值。SHA-1 是流行的用于创建数字签名的单向散列算法。
MAC(Message Authentication Code):消息认证代码,是一种使用密钥的单向函数,可以用它们在系统上或用户之间认证文件或消息,常见的是HMAC(用于消息认证的密钥散列算法)。
CRC(Cyclic Redundancy Check):循环冗余校验码,CRC校验由于实现简单,检错能力强,被广泛使用在各种数据校验应用中。占用系统资源少,用软硬件均能实现,是进行数据传输差错检测地一种很好的手段(CRC 并不是严格意义上的散列算法,但它的作用与散列算法大致相同,所以归于此类)。
数字签名:结合使用公钥与散列算法
数字签名是邮件、文件或其它数字编码信息的发件人将他们的身份与信息绑定在一起(即为信息提供签名)的方法。对信息进行数字签名的过程,需要将信息与由发件人掌握的秘密信息一起转换(使用私钥)为叫做签名的标记。数字签名用于公钥环境(任何人都可以拥有)中,它通过验证发件人确实是他或她所声明的那个人,并确认收到的邮件与发送的邮件完全相同。
散列算法处理数据的速度比公钥算法快得多。散列数据还缩短了要签名的数据的长度,因而加快了签名过程。
密钥交换:结合使用对称密钥与公钥
对称密钥算法非常适合于快速并安全地加密数据。但其缺点是,发件人和收件人必须在交换数据之前先交换机密密钥。结合使用加密数据的对称密钥算法与交换机密密钥的公钥算法可产生一种既快速又灵活的解决方案。
3.参考
openSSL命令、PKI、CA、SSL证书原理
X.509 wikipeida
PKI 基础知识
数字证书及CA的扫盲介绍

原文链接地址: http://seanlook.com/2015/01/15/openssl-certificate-encryption/

SSL/TLS原理详解

1.SSL/TLS概览

  •     1.1整体结构

SSL是一个介于HTTP协议与TCP之间的一个可选层,其位置大致如下:

SSL:(Secure Socket Layer,安全套接字层),为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取。当前版本为3.0。它已被广泛地用于Web浏览器与服务器之间的身份认证和加密数据传输。
SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通讯提供安全支持。SSL协议可分为两层: SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。 SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
TLS:(Transport Layer Security,传输层安全协议),用于两个应用程序之间提供保密性和数据完整性。
TLS 1.0是IETF(Internet Engineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本,可以理解为SSL 3.1,它是写入了 RFC 的。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。
SSL/TLS协议提供的服务主要有:
a)认证用户和服务器,确保数据发送到正确的客户机和服务器;
b)加密数据以防止数据中途被窃取;
c)维护数据的完整性,确保数据在传输过程中不被改变。

  •     1.2TLS与SSL的差异

1)版本号:TLS记录格式与SSL记录格式相同,但版本号的值不同,TLS的版本1.0使用的版本号为SSLv3.1。
2)报文鉴别码:SSLv3.0和TLS的MAC算法及MAC计算的范围不同。TLS使用了RFC-2104定义的HMAC算法。SSLv3.0使用了相似的算法,两者差别在于SSLv3.0中,填充字节与密钥之间采用的是连接运算,而HMAC算法采用的是异或运算。但是两者的安全程度是相同的。
3)伪随机函数:TLS使用了称为PRF的伪随机函数来将密钥扩展成数据块,是更安全的方式。
4)报警代码:TLS支持几乎所有的SSLv3.0报警代码,而且TLS还补充定义了很多报警代码,如解密失败(decryption_failed)、记录溢出(record_overflow)、未知CA(unknown_ca)、拒绝访问(access_denied)等。
5)密文族和客户证书:SSLv3.0和TLS存在少量差别,即TLS不支持Fortezza密钥交换、加密算法和客户证书。
6)certificate_verify和finished消息:SSLv3.0和TLS在用certificate_verify和finished消息计算MD5和SHA-1散列码时,计算的输入有少许差别,但安全性相当。
7)加密计算:TLS与SSLv3.0在计算主密值(master secret)时采用的方式不同。
8)填充:用户数据加密之前需要增加的填充字节。在SSL中,填充后的数据长度要达到密文块长度的最小整数倍。而在TLS中,填充后的数据长度可以是密文块长度的任意整数倍(但填充的最大长度为255字节),这种方式可以防止基于对报文长度进行分析的攻击。
TLS的主要增强内容
TLS的主要目标是使SSL更安全,并使协议的规范更精确和完善。TLS 在SSL v3.0 的基础上,提供了以下增强内容:
a)更安全的MAC算法
b)更严密的警报
c)“灰色区域”规范的更明确的定义
d)TLS对于安全性的改进
TLS对于安全性的改进
a)对于消息认证使用密钥散列法:TLS 使用“消息认证代码的密钥散列法”(HMAC),当记录在开放的网络(如因特网)上传送时,该代码确保记录不会被变更。SSLv3.0还提供键控消息认证,但HMAC比SSLv3.0使用的(消息认证代码)MAC 功能更安全。
b)增强的伪随机功能(PRF):PRF生成密钥数据。在TLS中,HMAC定义PRF。PRF使用两种散列算法保证其安全性。如果任一算法暴露了,只要第二种算法未暴露,则数据仍然是安全的。
c)改进的已完成消息验证:TLS和SSLv3.0都对两个端点提供已完成的消息,该消息认证交换的消息没有被变更。然而,TLS将此已完成消息基于PRF和HMAC值之上,这也比SSLv3.0更安全。
d)一致证书处理:与SSLv3.0不同,TLS试图指定必须在TLS之间实现交换的证书类型。
e)特定警报消息:TLS提供更多的特定和附加警报,以指示任一会话端点检测到的问题。TLS还对何时应该发送某些警报进行记录。

    2.密钥协商过程——TLS握手
SSL协议分为两部分:Handshake Protocol和Record Protocol。其中Handshake Protocol用来协商密钥,协议的大部分内容就是通信双方如何利用它来安全的协商出一份密钥。 Record Protocol则定义了传输的格式。
由于非对称加密的速度比较慢,所以它一般用于密钥交换,双方通过公钥算法协商出一份密钥,然后通过对称加密来通信,当然,为了保证数据的完整性,在加密前要先经过HMAC的处理。
SSL缺省只进行server端的认证,客户端的认证是可选的。以下是其流程图(摘自TLS协议)。

2.1 客户端发出请求(ClientHello)
由于客户端(如浏览器)对一些加解密算法的支持程度不一样,但是在TLS协议传输过程中必须使用同一套加解密算法才能保证数据能够正常的加解密。在TLS握手阶段,客户端首先要告知服务端,自己支持哪些加密算法,所以客户端需要将本地支持的加密套件(Cipher Suite)的列表传送给服务端。除此之外,客户端还要产生一个随机数,这个随机数一方面需要在客户端保存,另一方面需要传送给服务端,客户端的随机数需要跟服务端产生的随机数结合起来产生后面要讲到的 Master Secret 。
综上,在这一步,客户端主要向服务器提供以下信息:
1) 支持的协议版本,比如TLS 1.0版
2) 一个客户端生成的随机数,稍后用于生成”对话密钥”
3) 支持的加密方法,比如RSA公钥加密
4) 支持的压缩方法
2.2 服务器回应(SeverHello)
上图中,从Server Hello到Server Done,有些服务端的实现是每条单独发送,有服务端实现是合并到一起发送。Sever Hello和Server Done都是只有头没有内容的数据。
服务端在接收到客户端的Client Hello之后,服务端需要将自己的证书发送给客户端。这个证书是对于服务端的一种认证。例如,客户端收到了一个来自于称自己是www.alipay.com的数据,但是如何证明对方是合法的alipay支付宝呢?这就是证书的作用,支付宝的证书可以证明它是alipay,而不是财付通。证书是需要申请,并由专门的数字证书认证机构(CA)通过非常严格的审核之后颁发的电子证书。颁发证书的同时会产生一个私钥和公钥。私钥由服务端自己保存,不可泄漏。公钥则是附带在证书的信息中,可以公开的。证书本身也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以防止证书被串改。另外,证书还有个有效期。
在服务端向客户端发送的证书中没有提供足够的信息(证书公钥)的时候,还可以向客户端发送一个 Server Key Exchange,
此外,对于非常重要的保密数据,服务端还需要对客户端进行验证,以保证数据传送给了安全的合法的客户端。服务端可以向客户端发出 Cerficate Request 消息,要求客户端发送证书对客户端的合法性进行验证。比如,金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供USB密钥,里面就包含了一张客户端证书。
跟客户端一样,服务端也需要产生一个随机数发送给客户端。客户端和服务端都需要使用这两个随机数来产生Master Secret。
最后服务端会发送一个Server Hello Done消息给客户端,表示Server Hello消息结束了。
综上,在这一步,服务器的回应包含以下内容:
1) 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信
2) 一个服务器生成的随机数,稍后用于生成”对话密钥”
3) 确认使用的加密方法,比如RSA公钥加密
4) 服务器证书
2.3 客户端回应(Certificate Verify)
Client Key Exchange
如果服务端需要对客户端进行验证,在客户端收到服务端的 Server Hello 消息之后,首先需要向服务端发送客户端的证书,让服务端来验证客户端的合法性。
Certificate Verify
接着,客户端需要对服务端的证书进行检查,如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。如果证书没有问题,客户端就会从服务器证书中取出服务器的公钥。然后,向服务器发送下面三项信息:
1) 一个随机数。该随机数用服务器公钥加密,防止被窃听
2) 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送
3) 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验
上面第一项的随机数,是整个握手阶段出现的第三个随机数,它是客户端使用一些加密算法(例如:RSA, Diffie-Hellman)产生一个48个字节的Key,这个Key叫 PreMaster Secret,很多材料上也被称作 PreMaster Key。
ChangeCipherSpec
ChangeCipherSpec是一个独立的协议,体现在数据包中就是一个字节的数据,用于告知服务端,客户端已经切换到之前协商好的加密套件(Cipher Suite)的状态,准备使用之前协商好的加密套件加密数据并传输了。
在ChangecipherSpec传输完毕之后,客户端会使用之前协商好的加密套件和Session Secret加密一段 Finish 的数据传送给服务端,此数据是为了在正式传输应用数据之前对刚刚握手建立起来的加解密通道进行验证。
2.4 服务器的最后回应(Server Finish)
服务端在接收到客户端传过来的 PreMaster 加密数据之后,使用私钥对这段加密数据进行解密,并对数据进行验证,也会使用跟客户端同样的方式生成 Session Secret,一切准备好之后,会给客户端发送一个 ChangeCipherSpec,告知客户端已经切换到协商过的加密套件状态,准备使用加密套件和 Session Secret加密数据了。之后,服务端也会使用 Session Secret 加密一段 Finish 消息发送给客户端,以验证之前通过握手建立起来的加解密通道是否成功。
根据之前的握手信息,如果客户端和服务端都能对Finish信息进行正常加解密且消息正确的被验证,则说明握手通道已经建立成功,接下来,双方可以使用上面产生的Session Secret对数据进行加密传输了。
2.5 几个secret
Secret Keys
上面的分析和讲解主要是为了突出握手的过程,所以PreMaster secret,Master secret,session secret都是一代而过,但是对于Https,SSL/TLS深入的理解和掌握,这些Secret Keys是非常重要的部分。所以,准备把这些Secret Keys抽出来单独分析和讲解。
我们先来看看这些Secret Keys的生成过程以及作用流程图:

PreMaster secret
PreMaster Secret是在客户端使用RSA或者Diffie-Hellman等加密算法生成的。它将用来跟服务端和客户端在Hello阶段产生的随机数结合在一起生成 Master Secret。在客户端使用服务端的公钥对PreMaster Secret进行加密之后传送给服务端,服务端将使用私钥进行解密得到PreMaster secret。也就是说服务端和客户端都有一份相同的PreMaster secret和随机数。
PreMaster secret前两个字节是TLS的版本号,这是一个比较重要的用来核对握手数据的版本号,因为在Client Hello阶段,客户端会发送一份加密套件列表和当前支持的SSL/TLS的版本号给服务端,而且是使用明文传送的,如果握手的数据包被破解之后,攻击者很有可能串改数据包,选择一个安全性较低的加密套件和版本给服务端,从而对数据进行破解。所以,服务端需要对密文中解密出来对的PreMaster版本号跟之前Client Hello阶段的版本号进行对比,如果版本号变低,则说明被串改,则立即停止发送任何消息。
关于PreMaster Secret(Key)的计算请参考 Https SSL/TLS PreMaster/Master Secret(Key)计算。
Master secret
上面已经提到,由于服务端和客户端都有一份相同的PreMaster secret和随机数,这个随机数将作为后面产生Master secret的种子,结合PreMaster secret,客户端和服务端将计算出同样的Master secret。
Master secret是有系列的hash值组成的,它将作为数据加解密相关的secret的 Key Material 的一部分。Key Material最终解析出来的数据如下:

其中,write MAC key,就是session secret或者说是session key。Client write MAC key是客户端发数据的session secret,Server write MAC secret是服务端发送数据的session key。MAC(Message Authentication Code),是一个数字签名,用来验证数据的完整性,可以检测到数据是否被串改。
关于Session Secret(Key)的计算请参考 Https SSL/TLS Session Secret(Key)计算
    2.6 应用数据传输
在所有的握手阶段都完成之后,就可以开始传送应用数据了。应用数据在传输之前,首先要附加上MAC secret,然后再对这个数据包使用write encryption key进行加密。在服务端收到密文之后,使用Client write encryption key进行解密,客户端收到服务端的数据之后使用Server write encryption key进行解密,然后使用各自的write MAC key对数据的完整性包括是否被串改进行验证。
    2.7 总结
SSL客户端(也是TCP的客户端)在TCP链接建立之后,发出一个ClientHello来发起握手,这个消息里面包含了自己可实现的算法列表和其它一些需要的消息,SSL的服务器端会回应一个ServerHello,这里面确定了这次通信所需要的算法,然后发过去自己的证书(里面包含了身份和自己的公钥)。Client在收到这个消息后会生成一个秘密消息,用SSL服务器的公钥加密后传过去,SSL服务器端用自己的私钥解密后,会话密钥协商成功,双方可以用同一份会话密钥来通信了。
3. 附:密钥协商的形象化比喻
如果上面的说明不够清晰,这里我们用个形象的比喻,我们假设A与B通信,A是SSL客户端,B是SSL服务器端,加密后的消息放在方括号[]里,以突出明文消息的区别。双方的处理动作的说明用圆括号()括起。
A:我想和你安全的通话,我这里的对称加密算法有DES,RC5,密钥交换算法有RSA和DH,摘要算法有MD5和SHA。

B:我们用DES-RSA-SHA这对组合好了。
这是我的证书,里面有我的名字和公钥,你拿去验证一下我的身份(把证书发给A)。
目前没有别的可说的了。

A:(查看证书上B的名字是否无误,并通过手头早已有的CA的证书验证了B的证书的真实性,如果其中一项有误,发出警告并断开连接,这一步保证了B的公钥的真实性)
(产生一份秘密消息,这份秘密消息处理后将用作加密密钥,加密初始化向量(IV)和hmac的密钥。将这份秘密消息-协议中称为per_master_secret-用B的公钥加密,封装成称作ClientKeyExchange的消息。由于用了B的公钥,保证了第三方无法窃听)
我生成了一份秘密消息,并用你的公钥加密了,给你(把ClientKeyExchange发给B)
注意,下面我就要用加密的办法给你发消息了!
(将秘密消息进行处理,生成加密密钥,加密初始化向量和hmac的密钥)
[我说完了]

B:(用自己的私钥将ClientKeyExchange中的秘密消息解密出来,然后将秘密消息进行处理,生成加密密钥,加密初始化向量和hmac的密钥,这时双方已经安全的协商出一套加密办法了)
注意,我也要开始用加密的办法给你发消息了!
[我说完了]

A: [我的秘密是…]

B: [其它人不会听到的…]
4. SSL安全性
SecurityPortal在2000年底有一份文章《The End of SSL and SSH?》激起了很多的讨论, 目前也有一些成熟的工具如dsniff(http://www.monkey.org/~dugsong/dsniff/)可以通过man in the middle攻击来截获https的消息。
从上面的原理可知,SSL的结构是严谨的,问题一般出现在实际不严谨的应用中。常见的攻击就是middle in the middle攻击,它是指在A和B通信的同时,有第三方C处于信道的中间,可以完全听到A与B通信的消息,并可拦截,替换和添加这些消息。
1) SSL可以允许多种密钥交换算法,而有些算法,如DH,没有证书的概念,这样A便无法验证B的公钥和身份的真实性,从而C可以轻易的冒充,用自己的密钥与双方通信,从而窃听到别人谈话的内容。
而为了防止middle in the middle攻击,应该采用有证书的密钥交换算法。
2) 有了证书以后,如果C用自己的证书替换掉原有的证书之后,A的浏览器会弹出一个警告框进行警告,但又有多少人会注意这个警告呢?
3) 由于美国密码出口的限制,IE,netscape等浏览器所支持的加密强度是很弱的,如果只采用浏览器自带的加密功能的话,理论上存在被破解可能。
5. 代理
下面探讨一下SSL的代理是怎样工作的
当在浏览器里设置了https的代理,而且里输入了https://www.example.com之后,浏览器会与proxy建立tcp链接,然后向其发出这么一段消息:

CONNECT SERVER.EXAMPLE.COM:443 HTTP/1.1
HOST: SERVER.EXAMPLE.COM:443

然后proxy会向webserver端建立tcp连接,之后,这个代理便完全成了个内容转发装置。浏览器与web server会建立一个安全通道,因此这个安全通道是端到端的,尽管所有的信息流过了proxy,但其内容proxy是无法解密和改动的(当然要由证书的支持,否则这个地方便是个man in the middle攻击的好场所,见上面的安全部分)。
CA证书以及如何使用OpenSSL自签署,见文章OpenSSL自签署证书 。
6. 参考
Https(SSL/TLS)原理详解
SSL与TLS的区别以及介绍
SSL/TLS协议运行机制的概述
SSL/TLS/WTLS原理
Transport Layer Security (TLS)
传输层安全协议
Survival guides – TLS/SSL and SSL (X.509) Certificates

原文链接地址:https://segmentfault.com/a/1190000002554673

CA认证原理

1.什么是CA
认证中心(CA─Certificate Authority)作为权威的、可信赖的、公正的第三方机构,专门负责发放并管理所有参与网上交易的实体所需的数字证书。它作为一个权威机构,对密钥进行有效地管理,颁发证书证明密钥的有效性,并将公开密钥同某一个实体(消费者、商户、银行)联系在一起。
随着认证中心(或称CA中心)的出现,使得开放网络的安全问题得以迎刃而解。利用数字证书、PKI、对称加密算法、数字签名、数字信封等加密技术,可以建立起安全程度极高的加解密和身份认证系统,确保电子交易有效、安全地进行,从而使信息除发送方和接收方外,不被其他方知悉(保密性);保证传输过程中不被篡改(完整性和一致性);发送方确信接收方不是假冒的(身份的真实性和不可伪装性);发送方不能否认自己的发送行为(不可抵赖性)。
2.CA的架构
CA认证的主要工具是CA中心为网上作业主体颁发的数字证书。CA架构包括PKI结构、高强度抗攻击的公开加解密算法、数字签名技术、身份认证技术、运行安全管理技术、可靠的信任责任体系等等。从业务流程涉及的角色看, 包括认证机构、数字证书库和黑名单库、密钥托管处理系统、证书目录服务、证书审批和作废处理系统。从CA的层次结构来看, 可以分为认证中心(根CA)、密钥管理中心(KM)、认证下级中心(子CA)、证书审批中心(RA中心)、证书审批受理点(RAT)等。 CA中心一般要发布认证体系声明书,向服务的对象郑重声明CA的政策、保证安全的措施、服务的范围、服务的质量、承担的责任、操作流程等条款。
根据PKI的结构, 身份认证的实体需要有一对密钥, 分别为私钥和公钥。 其中的私钥是保密的, 公钥是公开的。从原理上讲, 不能从公钥推导出私钥,穷举法来求私钥则由于目前的技术、运算工具和时间的限制而不可能。每个实体的密钥总是成对出现,即一个公钥必定对应一个私钥。公钥加密的信息必须由对应的私钥才能解密,同样,私钥做出的签名, 也只有配对的公钥才能解密。 公钥有时用来传输对称密钥,这就是数字信封技术。 密钥的管理政策是把公钥和实体绑定, 由CA中心把实体的信息和实体的公钥制作成数字证书, 证书的尾部必须有CA中心的数字签名。 由于CA中心的数字签名是不可伪造的, 因此实体的数字证书不可伪造。CA中心对实体的物理身份资格审查通过后,才对申请者颁发数字证书, 将实体的身份与数字证书对应起来。由于实体都信任提供第三方服务的CA中心, 因此, 实体可以信任由CA中心颁发数字证书的其他实体, 放心地在网上进行作业和交易。
3.CA的职责
CA中心主要职责是颁发和管理数字证书。 其中心任务是颁发数字证书,并履行用户身份认证的责任。CA中心在安全责任分散、运行安全管理、系统安全、物理安全、数据库安全、人员安全、密钥管理等方面, 需要十分严格的政策和规程,要有完善的安全机制。另外要有完善的安全审计、运行监控、容灾备份、事故快速反应等实施措施, 对身份认证、访问控制、防病毒防攻击等方面也要有强大的工具支撑。CA中心的证书审批业务部门则负责对证书申请者进行资格审查, 并决定是否同意给该申请者发放证书,并承担因审核错误引起的、为不满足资格的证书申请者发放证书所引起的一切后果, 因此, 它应是能够承担这些责任的机构担任;证书操作部门(Certificate Processor,简称CP)负责为已授权的申请者制作、发放和管理证书, 并承担因操作运营错误所产生的一切后果, 包括失密和为没有授权者发放证书等, 它可以由审核业务部门自己担任, 也可委托给第三方担任。
4.RA
RA(Registration Authority),数字证书注册审批机构。RA系统是CA的证书发放、管理的延伸。它负责证书申请者的信息录入、审核以及证书发放等工作;同时,对发放的证书完成相应的管理功能。发放的数字证书可以存放于IC卡、硬盘或软盘等介质中。RA系统是整个CA中心得以正常运营不可缺少的一部分。
5.数字证书
数字安全证书就是标志网络用户身份信息的一系列数据,用来在网络通讯中识别通讯各方的身份,即要在Internet上解决”我是谁”的问题,就如同现实中我们每一个人都要拥有一张证明个人身份的身份证或驾驶执照一样,以表明我们的身份或某种资格。
在网上电子交易中, 商户需要确认持卡人是信用卡或借记卡的合法持有者,同时持卡人也必须能够鉴别商户是否是合法商户,是否被授权接受某种品牌的信用卡或借记卡支付。为处理这些关键问题,必须有一个大家都信赖的机构来发放数字安全证书。数字安全证书就是参与网上交易活动的各方(如持卡人、商家、支付网关) 身份的代表,每次交易时,都要通过数字安全证书对各方的身份进行验证。数字安全证书是由权威公正的第三方机构即CA中心签发的,它在证书申请被认证中心批准后,通过登记服务机构将证书发放给申请者。
数字安全证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件。最简单的证书包含一个公开密钥、名称以及证书授权中心的数字签名。一般情况下证书中还包括密钥的有效时间,发证机关(证书授权中心)的名称,该证书的序列号等信息,证书的格式遵循ITUT X.509国际标准。
一个标准的X.509数字安全证书包含以下一些内容:
证书的版本信息;
证书的序列号,每个证书都有一个唯一的证书序列号;
证书所使用的签名算法;
证书的发行机构名称,命名规则一般采用X.500格式;
证书的有效期,现在通用的证书一般采用UTC时间格式;
证书所有人的名称,命名规则一般采用X.500格式;
证书所有人的公开密钥;
证书发行者对证书的签名。

LOG!LOG!LOG!重要的事要说3遍!

前两天刚自己查pptpd的debug log找问题,今天竟然一再犯同样的错误,不可原谅么…
nginx.org上边就给出了rewrite选项的配置,我竟然视而不见,在傻傻的google,盲目的改rewrite,systemctl restart nginx,去QQ群找大神,what the fuck!能再2一点不.
还好,在我最暴躁的时候,还是QQ里边的大神”杰出青年@LFS/Gentoo/Arch超级群”点醒了我,”打开 rewrite log,自己调试”,感谢!

一翻对比下来,发现rewrite规则并没有出错,出错的一直都是自己,what the fuck!虽然一切都看起来很正常,但yii还是死活不能正常的跑起来,DAMN IT!

正一筹莫展的时候,突然想起了centos7有个命令”getenforce”,好吧,在鼓下”setenforce 0″的时候,终于一切正常了…

真的一切正常了吗?

记录一下rewrite规则…

        location /api/
        {
            if (!-e $request_filename){
            rewrite ^(.+)$ /api/index.php?q=$1 last;
            #rewrite ^(.+)$ /api/index.php?$1 last;
            #rewrite ^(.+)$ /api/index.php?$1& last;    # all worked
            }
         }

VPN连接出现LCP: timeout sending Config-Requests和unexpected termination of pppd解决办法

vultr上边新开了个VPS装centos7用来做vpn翻墙,装好ppp和pptpd后卡用户验证这一栏.
看了下系统log,记录如下:

tail -20 /var/log/messages
  n 29 04:14:12 vultr pptpd[17292]: CTRL: Client 113.89.11.152 control connection started
▽n 29 04:14:12 vultr pptpd[17292]: CTRL: Starting call (launching pppd, opening GRE)
Jan 29 04:14:12 vultr pppd[17293]: pppd 2.4.5 started by root, uid 0
Jan 29 04:14:12 vultr pppd[17293]: Using interface ppp0
Jan 29 04:14:12 vultr pppd[17293]: Connect: ppp0 <--> /dev/pts/1
Jan 29 04:14:42 vultr pppd[17293]: LCP: timeout sending Config-Requests
Jan 29 04:14:42 vultr pppd[17293]: Connection terminated.
Jan 29 04:14:42 vultr pppd[17293]: Modem hangup
Jan 29 04:14:42 vultr pppd[17293]: Exit.
Jan 29 04:14:42 vultr pptpd[17292]: GRE: read(fd=6,buffer=7f8d2efe4480,len=8196) from PTY failed: status = -1 error = Input/output error, usually caused by unexpected termination of pppd, check option syntax andpppd logs
Jan 29 04:14:42 vultr pptpd[17292]: CTRL: PTY read or GRE write failed (pty,gre)=(6,7)
Jan 29 04:14:42 vultr pptpd[17292]: CTRL: Client 113.89.11.152 control connection finished

google用关键字”pptp gre”,”usually caused by unexpected termination of pppd”等找出来的各种解决办法,包括注释掉”logwtmp”,”升级路由bois”等等,问题依然.
看来原因还是要自己一步一步找,于是打开”pptpd.conf”的debug选项,再在”/etc/rsyslog.conf”末添加:

*.debug        /var/log/ppp/pptpd.log

重启pptpd后再”cat pptpd.log”:

▽n 29 04:37:06 vultr systemd: Stopping System Logging Service...
Jan 29 04:37:06 vultr systemd: Starting System Logging Service...
Jan 29 04:37:06 vultr systemd: Started System Logging Service.
Jan 29 04:37:15 vultr pptpd[17474]: MGR: Launching /usr/sbin/pptpctrl to handle client
Jan 29 04:37:15 vultr pptpd[17474]: CTRL: local address = 10.10.0.1
Jan 29 04:37:15 vultr pptpd[17474]: CTRL: remote address = 10.10.0.100
Jan 29 04:37:15 vultr pptpd[17474]: CTRL: pppd options file = /etc/ppp/options.pptpd
Jan 29 04:37:15 vultr pptpd[17474]: CTRL: Client 113.89.11.152 control connection started
Jan 29 04:37:15 vultr pptpd[17474]: CTRL: Received PPTP Control Message (type: 1)
Jan 29 04:37:15 vultr pptpd[17474]: CTRL: Made a START CTRL CONN RPLY packet
Jan 29 04:37:15 vultr pptpd[17474]: CTRL: I wrote 156 bytes to the client.
Jan 29 04:37:15 vultr pptpd[17474]: CTRL: Sent packet to client
Jan 29 04:37:16 vultr pptpd[17474]: CTRL: Received PPTP Control Message (type: 7)
Jan 29 04:37:16 vultr pptpd[17474]: CTRL: Set parameters to 100000000 maxbps, 64 window size
Jan 29 04:37:16 vultr pptpd[17474]: CTRL: Made a OUT CALL RPLY packet
Jan 29 04:37:16 vultr pptpd[17474]: CTRL: Starting call (launching pppd, opening GRE)
Jan 29 04:37:16 vultr pptpd[17474]: CTRL: pty_fd = 6
Jan 29 04:37:16 vultr pptpd[17474]: CTRL: tty_fd = 7
Jan 29 04:37:16 vultr pptpd[17474]: CTRL: I wrote 32 bytes to the client.
Jan 29 04:37:16 vultr pptpd[17474]: CTRL: Sent packet to client
Jan 29 04:37:16 vultr pptpd[17475]: CTRL (PPPD Launcher): program binary = /usr/sbin/pppd
Jan 29 04:37:16 vultr pptpd[17475]: CTRL (PPPD Launcher): local address = 10.10.0.1
Jan 29 04:37:16 vultr pptpd[17475]: CTRL (PPPD Launcher): remote address = 10.10.0.100
Jan 29 04:37:16 vultr pppd[17475]: Plugin /usr/lib64/pptpd/pptpd-logwtmp.so loaded.
Jan 29 04:37:16 vultr pppd[17475]: pppd 2.4.5 started by root, uid 0
Jan 29 04:37:16 vultr pppd[17475]: Using interface ppp0
Jan 29 04:37:16 vultr pppd[17475]: Connect: ppp0 <--> /dev/pts/3
Jan 29 04:37:16 vultr pptpd[17474]: CTRL: Received PPTP Control Message (type: 15)
Jan 29 04:37:16 vultr pptpd[17474]: CTRL: Got a SET LINK INFO packet with standard ACCMs
Jan 29 04:37:46 vultr pppd[17475]: LCP: timeout sending Config-Requests
Jan 29 04:37:46 vultr pppd[17475]: Connection terminated.
Jan 29 04:37:46 vultr pppd[17475]: Modem hangup
Jan 29 04:37:46 vultr pppd[17475]: Exit.
Jan 29 04:37:46 vultr pptpd[17474]: GRE: read(fd=6,buffer=7ff7e780e480,len=8196) from PTY failed: status = -1 error = Input/output error, usually caused by unexpected termination of pppd, check option syntax andpppd logs
Jan 29 04:37:46 vultr pptpd[17474]: CTRL: PTY read or GRE write failed (pty,gre)=(6,7)
Jan 29 04:37:46 vultr pptpd[17474]: CTRL: Reaping child PPP[17475]
Jan 29 04:37:46 vultr pptpd[17474]: CTRL: Client 113.89.11.152 control connection finished
Jan 29 04:37:46 vultr pptpd[17474]: CTRL: Exiting now

我去,几乎没有区别麻…只好根据log从上到下一个个排查了.google关键字从”LCP: timeout sending Config-Requests”开始.
终于在”Can’t connect to VPN on Fedora 21“这里找到答案:

Also seeing “LCP: timeout sending Config-Requests” reported in journalctl. I seems that the firewall is blocking GRE, I added rules to accept GRE via the commandline and now I’m able to setup my VPN:

firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p gre -j ACCEPT
firewall-cmd --direct --add-rule ipv6 filter INPUT 0 -p gre -j ACCEPT
firewall-cmd --reload

Hidde Boonstra (Feb 10 ’15)

顺道记录一下centos7下边的ppp,pptpd安装配置过程:

#rpm -Uvh http://download.fedoraproject.org/pub/epel/beta/7/x86_64/epel-release-7-1.noarch.rpm
#yum -y install ppp pptpd

#echo 'localip 10.10.0.1' >> /etc/pptpd.conf
#echo 'remoteip 10.10.0.100-199' >> /etc/pptpd.conf

#echo 'ms-dns 8.8.8.8' >> /etc/ppp/options.pptpd
#echo 'ms-dns 8.8.4.4' >> /etc/ppp/options.pptpd

#echo 'USERNAME pptpd PASSWORD *' >> /etc/ppp/chap-secrets

#echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf

#sysctl -p

#firewall-cmd --permanent --new-service=pptpd

#cat >/etc/firewalld/services/pptpd.xml<<EOF
<?xml version="1.0" encoding="utf-8"?>
<service>
  <port protocol="tcp" port="1723"/>
</service>
EOF
#firewall-cmd --permanent --zone=public --add-service=pptpd
#firewall-cmd --permanent --zone=public --add-masquerade
#firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p gre -j ACCEPT
#firewall-cmd --direct --add-rule ipv6 filter INPUT 0 -p gre -j ACCEPT
#firewall-cmd --reload

#systemctl start pptpd
#systemctl enable pptpd.service

test命令

人老了,老记不起,mark一下

测试的标志 代表意义
1. 关于某个档名的『文件类型』判断,如 test -e filename 表示存在否
-e 该『档名』是否存在?(常用)
-f 该『档名』是否存在且为档案(file)?(常用)
-d 该『文件名』是否存在且为目录(directory)?(常用)
-b 该『档名』是否存在且为一个 block device 装置?
-c 该『档名』是否存在且为一个 character device 装置?
-S 该『档名』是否存在且为一个 Socket 档案?
-p 该『档名』是否存在且为一个 FIFO (pipe) 档案?
-L 该『档名』是否存在且为一个连结档?
2. 关于档案的权限侦测,如 test -r filename 表示可读否 (但 root 权限常有例外)
-r 侦测该档名是否存在且具有『可读』的权限?
-w 侦测该档名是否存在且具有『可写』的权限?
-x 侦测该档名是否存在且具有『可执行』的权限?
-u 侦测该文件名是否存在且具有『SUID』的属性?
-g 侦测该文件名是否存在且具有『SGID』的属性?
-k 侦测该文件名是否存在且具有『Sticky bit』的属性?
-s 侦测该档名是否存在且为『非空白档案』?
3. 两个档案之间的比较,如: test file1 -nt file2
-nt (newer than)判断 file1 是否比 file2 新
-ot (older than)判断 file1 是否比 file2 旧
-ef 判断 file1 与 file2 是否为同一档案,可用在判断 hard link 的判定上。 主要意义在判定,两个档案是否均指向同一个 inode 哩!
4. 关于两个整数之间的判定,例如 test n1 -eq n2
-eq 两数值相等 (equal)
-ne 两数值不等 (not equal)
-gt n1 大于 n2 (greater than)
-lt n1 小于 n2 (less than)
-ge n1 大于等于 n2 (greater than or equal)
-le n1 小于等于 n2 (less than or equal)
5. 判定字符串的数据
test -z string 判定字符串是否为 0 ?若 string 为空字符串,则为 true
test -n string 判定字符串是否非为 0 ?若 string 为空字符串,则为 false。
注: -n 亦可省略
test str1 == str2 判定 str1 是否等于 str2 ,若相等,则回传 true
test str1 != str2 判定 str1 是否不等于 str2 ,若相等,则回传 false
6. 多重条件判定,例如: test -r filename -a -x filename
-a (and)两状况同时成立!例如 test -r file -a -x file,则 file 同时具有 r 与 x 权限时,才回传 true。
-o (or)两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 或 x 权限时,就可回传 true。
! 反相状态,如 test ! -x file ,当 file 不具有 x 时,回传 true

 

解壓縮後的 SELinux 課題

    注:标记一下,值得关注的问题.

如果,鳥哥是說如果,如果因為某些緣故,所以你的系統必須要以備份的資料來回填到原本的系統中,那麼得要特別注意復原後的系統的 SELinux 問題! 尤其是在系統檔上面!例如 /etc 底下的檔案群。SELinux 是比較特別的細部權限設定,相關的介紹我們會在 16 章好好的介紹一下。 在這裡,你只要先知道,SELinux 的權限問題『可能會讓你的系統無法存取某些設定檔內容,導致影響到系統的正常使用權』。

這兩天 (2015/07) 接到一個網友的 email,他說他使用鳥哥介紹的方法透過 tar 去備份了 /etc 的資料,然後嘗試在另一部系統上面復原回來。 復原倒是沒問題,但是復原完畢之後,無論如何就是無法正常的登入系統!明明使用單人維護模式去操作系統時,看起來一切正常~但就是無法順利登入。 其實這個問題倒是很常見!大部分原因就是因為 /etc/shadow 這個密碼檔案的 SELinux 類型在還原時被更改了!導致系統的登入程序無法順利的存取它, 才造成無法登入的窘境。

那如何處理呢?簡單的處理方式有這幾個:

  • 透過各種可行的救援方式登入系統,然後修改 /etc/selinux/config 檔案,將 SELinux 改成 permissive 模式,重新開機後系統就正常了;
  • 在第一次復原系統後,不要立即重新開機!先使用 restorecon -Rv /etc 自動修復一下 SELinux 的類型即可。
  • 透過各種可行的方式登入系統,建立 /.autorelabel 檔案,重新開機後系統會自動修復 SELinux 的類型,並且又會再次重新開機,之後就正常了!
  • 鳥哥個人是比較偏好第 2 個方法,不過如果忘記了該步驟就重新開機呢?那鳥哥比較偏向使用第 3 個方案來處理,這樣就能夠解決復原後的 SELinux 問題囉! 至於更詳細的 SELinux ,我們得要講完程序 (process) 之後,你才會有比較清楚的認知,因此還請慢慢學習,到第 16 章你就知道問題點了! ^_^

    来源:http://linux.vbird.org/linux_basic/0240tarcompress.php#pack

    CentOS7強制使用 GPT 分割表的安裝參數

    Centos7光盘引导安装的话会自动检测计算机硬件,如果检测到的硬盘小于2T则会默认安装MSDOS MBR来引导CentOS,而非GPT.如果想要强制安装GTP则要在开始安装前加入inst.gpt参数,如下图:
    centos7_02
    1.用方向键选中”Install CentOS 7″选项.
    2.按Tab键,CentOS安装引导程序会将安装参数命令行显示在屏幕最下方,并且光标自动定位在默认安装参数行末.
    3.在默认安装参数行末键入空格,添加”inst.gpt”参数.回车.
    后面的安装设置满大街,不再重述了…

    引用来源:http://linux.vbird.org/linux_basic/0157installcentos7.php