1.理论知识
https简介
HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息。HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此HTTP协议不适合传输一些敏感信息,比如信用卡号、密码等。
为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS。为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
HTTPS和HTTP的区别主要为以下四点:
- https协议需要到ca申请证书,一般免费证书很少,需要交费。
- http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。
- http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
简单的说,https就是在http的基础上嵌套SSL协议,由此来实现身份认证,要理解SSL,还要说明一下非对称加密体系。
非对称加密
有非对称加密,那么当然也有对称加密,下面简单说一下这两者的区别。
- 对称加密:指的是加密和解密使用的是同一个密钥,发送者使用秘钥A对信息加密,然后传送密文,接受者使用密钥A对密文解密,得到信息。若此时使用密钥B解密此密文,则无法进行解密。为了保证加密的可靠性,发送者和接受者都要保证密钥A不被泄露。
- 非对称加密:使用一对密钥进行加密和解密操作,分别称为公钥和私钥,公钥和私钥是成对生成的,公钥往往是公开的,任何人都可以得到,私钥是保密的,只有特定的人才拥有。非对称加密有两种典型的使用情况,分别是加密和验证。
- 加密:加密是为了传送需要保密的信息,所以需要保证只有特定的人才可以对信息进行解密。于是发送者使用公钥A加密,接受者使用私钥A解密。假设所有人都拥有公钥A,只有张三有私钥A,那么,其他人想要给张三发送信息,只需要将信息使用公钥A加密,那么密文只有拥有私钥A的张三才可以解密。
- 验证:验证是为了向其他人证明“我就是我”的问题。在这里,发送者使用私钥进行A签名,接受者使用公钥A进行验证。还是假设所有人都拥有公钥A,只有张三有私钥A,现在张三要向其他人证明自己就是张三,于是张三将“我是张三”这段信息使用私钥A进行签名,发送给其他人,其他人使用公钥A解密,得到签名“我是张三”,于是其他人就认为这段信息是张三发送的。这里有一个问题,就是任何人都可以使用自己的私钥将“我是张三”签名,从而仿冒张三,假设此时有一个李四,他用自己的私钥B签名“我是张三”,这使其他拥有公钥B的人会认为李四就是张三。解决这个问题的方法就是保证验证公钥的权威性,CA就是为了解决这个问题,CA(Certificate Authority),也称为电子商务认证中心,是负责发放和管理数字证书的权威机构,并作为电子商务交易中受信任的第三方,承担公钥体系中公钥的合法性检验的责任。CA具体流程下面再说。
https建立流程
首先上图,这张图显示了https建立的流程。
下面简单解释一下这个流程:
- CA建立,并颁发给自己根证书。即CA使用自己的私钥,将CA的验证信息和自己的公钥打包加密成根证书。
- CA与浏览器厂商(browser vendor)联系,告诉浏览器厂商自己的证书,如果浏览器厂商信任这个CA,就会把这个CA的证书加入到自己开发的浏览器中。
- 一个想要获取https服务的网站,首先要将自己的验证信息和自己的公钥发送给CA,并向CA申请自己的证书,CA在验证这个网站的合法性之后,会用CA自己的私钥对网站的验证信息和公钥打包加密,形成这个网站的证书,并将这个证书颁发给网站。
- 现在网站已经有了自己的证书了,于是他可以搭建自己的https服务。
- 现在一个客户端要使用网站的https服务,网站会将自己的证书发送给客户端。客户端使用CA的证书对网站证书进行验证,核实无误后建立安全连接,即SSL握手过程。
- 由客户端开始。客户端发送SSL版本,以及加密和压缩算法给服务器。服务器检查是否支持此版本SSL,并启动客户端期望的加密和压缩算法。
- 基础配置完毕后,服务器发送自己的证书。该证书必须被客户端信任,或者被客户端信任的CA所信任。
- 客户端验证证书,并核实服务器的身份是正确的。
- 验证完毕后,两者协商之后使用的加密方式,并且客户端告诉服务器,从现在起,所有数据互换都是加密的,并发送一个加密的验证”消息“给服务器。
- 服务器验证是客户端发送的,并且”消息“可以被解密。服务器将解密后的”消息“发送给客户端。客户端核实后,安全连接。握手结束。
- 之后,客户端和服务器可以使用https服务进行加密通信了,不过之后的通信一般使用对称加密算法来实现,因为相较于非对称加密,对称加密所占资源更少。
2.搭建https服务
本机环境:Ubuntu 17.10 , Openssl 1.0.2g , FireFox 57.0.1 (64 位) , Apache 2.4.27
首先确认安装OpenSSL
确定OpenSSL版本:
$openssl version
如果版本低于1.0.1f,建议升级,因为1.0.1f版本之下的OpenSSL有一个Heartbleed漏洞。
安装OpenSSL:
$sudo apt-get install openssl
自建CA
因为向CA申请签名是需要收费的,所以我们选择自己搭建一个CA来完成这个实验过程。
首先建立myCA目录用于存放CA相关信息
cd && mkdir -p myCA/signedcerts && mkdir myCA/private && cd myCA
myCA 用于存放 CA 根证书,证书数据库,以及后续服务器生成的证书,密钥以及请求
signedcerts:保存签名证书的 copy
private: 包含私钥
之后配置myCA相关参数,在myCA目录下进行
echo ‘01‘>serial && touh index.txt
然后创建 caconfig.cnf 文件
vim ~/myCA/caconfig.cnf
caconfig.cnf文件内容如下
# My sample caconfig.cnf file.## Default configuration to use when one is not provided on the command line.#[ ca ]default_ca ?????= local_ca### Default location of directories and files needed to generate certificates.#[ local_ca ]dir ????????????= /home/<username>/myCA ???????????????????# 这里要将username替换为你的用户名certificate ????= $dir/cacert.pemdatabase ???????= $dir/index.txtnew_certs_dir ??= $dir/signedcertsprivate_key ????= $dir/private/cakey.pemserial ?????????= $dir/serial# ??????## Default expiration and encryption policies for certificates.#default_crl_days ???????= 365default_days ???????????= 1825default_md ?????????????= SHA256# ??????policy ?????????= local_ca_policyx509_extensions = local_ca_extensions# ??????## Default policy to use when generating server certificates. ?The following# fields must be defined in the server certificate.#[ local_ca_policy ]commonName ?????????????= suppliedstateOrProvinceName ????= suppliedcountryName ????????????= suppliedemailAddress ???????????= suppliedorganizationName ???????= suppliedorganizationalUnitName ?= supplied# ??????## x509 extensions to use when generating server certificates.#[ local_ca_extensions ]subjectAltName ?????????= DNS:localhostbasicConstraints ???????= CA:falsensCertType ?????????????= server# ??????## The default root certificate generation policy.#[ req ]default_bits ???= 2048default_keyfile = /home/<username>/myCA/private/cakey.pem ?# 这里要将username替换为你的用户名default_md ?????= SHA256# ??????prompt ?????????????????= nodistinguished_name ?????= root_ca_distinguished_namex509_extensions ????????= root_ca_extensions### Root Certificate Authority distinguished name. ?Change these fields to match# your local environment!#[ root_ca_distinguished_name ]commonName ?????????????= MyOwn Root Certificate Authority # CA机构名stateOrProvinceName ????= JS ??????????????????????????????# CA所在省份countryName ????????????= CN ??????????????????????????????# CA所在国家(仅限2个字符)emailAddress ???????????= XXXX@XXX.com ????????????????????# 邮箱organizationName ???????= XXX ?????????????????????????????# organizationalUnitName ?= XXX ?????????????????????????????# # ??????[ root_ca_extensions ]basicConstraints ???????= CA:true
生成 CA 根证书和密钥
export OPENSSL_CONF=~/myCA/caconfig.cnf ??????#该命令用于给环境变量 OPENSSL_CONF 赋值为caconfig.cnf。openssl req -x509 -newkey rsa:2048 -out cacert.pem -outform PEM -days 1825 ????????????# 生成 CA 根证书和密钥
该命令需要用户设置密码。不要忘记。
以上步骤生成了 CA 自签名根证书,和 RSA 公/私密钥对。证书的格式是 PEM,有效期是1825天。
- /myCA/cacert.pem: CA 根证书
- /myCA/private/cakey.pem: CA 私钥
创建服务器公私钥
生成服务器配置文件exampleserver.cnf
vim ~/myCA/exampleserver.cnf
exampleserver.cnf文件内容如下
## exampleserver.cnf#[ req ]prompt ????????????= nodistinguished_name = server_distinguished_name[ server_distinguished_name ]commonName ?????????????= localhost ?????????# 服务器域名stateOrProvinceName ????= JS ????????????????# 服务器所在省份countryName ????????????= CN ????????????????# 服务器所在国家(仅限2个字符)emailAddress ???????????= XXXX@XXX.com ??????# 邮箱organizationName ???????= XXX ???????????????# organizationalUnitName ?= XXX ???????????????#
生成服务器证书和密钥
export OPENSSL_CONF =~/myCA/exampleserver.cnf ??# 该命令设置环境变量 OPENSSL_CONF,使得 openssl 更换配置文件。openssl req -newkey rsa:1024 -keyout tempkey.pem -keyform PEM -out tempreq.pem -outform PEM
同样的,需要输入密码短语。
之后,有2种对临时秘钥的操作,选择其一即可
1.将临时私钥转换为 unencrypted key,即秘钥不加密状态。
penssl rsa -in tempkey.pem -out server_key.pem
需要输入密码短语。
2.如果希望将 key 保持为加密状态,直接改名
mv tempkey.pem server_key.pem
两者的区别是,第二种需要在服务器启动时输入私钥的密码短语,否则会导致服务器启动失败,但第二种安全性高于第一种,可以更好的保护秘钥。
使用 CA key 对服务器证书签名
export OPENSSL_CONF=~/myCA/caconfig.cnfopenssl ca -in tempkey.pem -out server_crt.pem
删除临时证书和密码文件
rm -f tempkey.pem && rm -f tempreq.pem
现在,自签名的服务器证书和密钥对便产生了:
- server_crt.pem : 服务器证书文件
- server_key.pem : 服务器密钥文件
配置 Apache
建立ssl配置文件,lab-ssl.conf
vim /etc/apache2/sites-available/lab-ssl.conf
lab-ssl.conf文件内容如下
<IfModule mod_ssl.c> ???<VirtualHost _default_:443> ???????ServerAdmin webmaster@localhost ???????DocumentRoot /var/www/lab ?????????????????????????????# 网站目录 ???????# Available loglevels: trace8, ..., trace1, debug, info, notice, warn, ???????# error, crit, alert, emerg. ???????# It is also possible to configure the loglevel for particular ???????# modules, e.g. ???????#LogLevel info ssl:warn ???????ErrorLog ${APACHE_LOG_DIR}/error.log ???????CustomLog ${APACHE_LOG_DIR}/access.log combined ???????# For most configuration files from conf-available/, which are ???????# enabled or disabled at a global level, it is possible to ???????# include a line for only one particular virtual host. For example the ???????# following line enables the CGI configuration for this host only ???????# after it has been globally disabled with "a2disconf". ???????#Include conf-available/serve-cgi-bin.conf ???????# ??SSL Engine Switch: ???????# ??Enable/Disable SSL for this virtual host. ???????SSLEngine on ???????# ??A self-signed (snakeoil) certificate can be created by installing ???????# ??the ssl-cert package. See ???????# ??/usr/share/doc/apache2/README.Debian.gz for more info. ???????# ??If both key and certificate are stored in the same file, only the ???????# ??SSLCertificateFile directive is needed. ???????#SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem ???????#SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key ???????# 网站证书和私钥地址 ???????SSLCertificateFile ???/home/libaoquan/myCA/server_crt.pem ???????SSLCertificateKeyFile /home/libaoquan/myCA/server_key.pem ???????# ??Server Certificate Chain: ???????# ??Point SSLCertificateChainFile at a file containing the ???????# ??concatenation of PEM encoded CA certificates which form the ???????# ??certificate chain for the server certificate. Alternatively ???????# ??the referenced file can be the same as SSLCertificateFile ???????# ??when the CA certificates are directly appended to the server ???????# ??certificate for convinience. ???????#SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt ???????# ??Certificate Authority (CA): ???????# ??Set the CA certificate verification path where to find CA ???????# ??certificates for client authentication or alternatively one ???????# ??huge file containing all of them (file must be PEM encoded) ???????# ??Note: Inside SSLCACertificatePath you need hash symlinks ???????# ???????to point to the certificate files. Use the provided ???????# ???????Makefile to update the hash symlinks after changes. ???????#SSLCACertificatePath /etc/ssl/certs/ ???????#SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt ???????# ??Certificate Revocation Lists (CRL): ???????# ??Set the CA revocation path where to find CA CRLs for client ???????# ??authentication or alternatively one huge file containing all ???????# ??of them (file must be PEM encoded) ???????# ??Note: Inside SSLCARevocationPath you need hash symlinks ???????# ???????to point to the certificate files. Use the provided ???????# ???????Makefile to update the hash symlinks after changes. ???????#SSLCARevocationPath /etc/apache2/ssl.crl/ ???????#SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl ???????# ??Client Authentication (Type): ???????# ??Client certificate verification type and depth. ?Types are ???????# ??none, optional, require and optional_no_ca. ?Depth is a ???????# ??number which specifies how deeply to verify the certificate ???????# ??issuer chain before deciding the certificate is not valid. ???????#SSLVerifyClient require ???????#SSLVerifyDepth ?10 ???????# ??SSL Engine Options: ???????# ??Set various options for the SSL engine. ???????# ??o FakeBasicAuth: ???????# ???Translate the client X.509 into a Basic Authorisation. ?This means that ???????# ???the standard Auth/DBMAuth methods can be used for access control. ?The ???????# ???user name is the `one line‘ version of the client‘s X.509 certificate. ???????# ???Note that no password is obtained from the user. Every entry in the user ???????# ???file needs this password: `xxj31ZMTZzkVA‘. ???????# ??o ExportCertData: ???????# ???This exports two additional environment variables: SSL_CLIENT_CERT and ???????# ???SSL_SERVER_CERT. These contain the PEM-encoded certificates of the ???????# ???server (always existing) and the client (only existing when client ???????# ???authentication is used). This can be used to import the certificates ???????# ???into CGI scripts. ???????# ??o StdEnvVars: ???????# ???This exports the standard SSL/TLS related `SSL_*‘ environment variables. ???????# ???Per default this exportation is switched off for performance reasons, ???????# ???because the extraction step is an expensive operation and is usually ???????# ???useless for serving static content. So one usually enables the ???????# ???exportation for CGI and SSI requests only. ???????# ??o OptRenegotiate: ???????# ???This enables optimized SSL connection renegotiation handling when SSL ???????# ???directives are used in per-directory context. ???????#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire ???????<FilesMatch "\.(cgi|shtml|phtml|php)$"> ???????????????SSLOptions +StdEnvVars ???????</FilesMatch> ???????<Directory /usr/lib/cgi-bin> ???????????????SSLOptions +StdEnvVars ???????</Directory> ???????# ??SSL Protocol Adjustments: ???????# ??The safe and default but still SSL/TLS standard compliant shutdown ???????# ??approach is that mod_ssl sends the close notify alert but doesn‘t wait for ???????# ??the close notify alert from client. When you need a different shutdown ???????# ??approach you can use one of the following variables: ???????# ??o ssl-unclean-shutdown: ???????# ???This forces an unclean shutdown when the connection is closed, i.e. no ???????# ???SSL close notify alert is send or allowed to received. ?This violates ???????# ???the SSL/TLS standard but is needed for some brain-dead browsers. Use ???????# ???this when you receive I/O errors because of the standard approach where ???????# ???mod_ssl sends the close notify alert. ???????# ??o ssl-accurate-shutdown: ???????# ???This forces an accurate shutdown when the connection is closed, i.e. a ???????# ???SSL close notify alert is send and mod_ssl waits for the close notify ???????# ???alert of the client. This is 100% SSL/TLS standard compliant, but in ???????# ???practice often causes hanging connections with brain-dead browsers. Use ???????# ???this only for browsers where you know that their SSL implementation ???????# ???works correctly. ???????# ??Notice: Most problems of broken clients are also related to the HTTP ???????# ??keep-alive facility, so you usually additionally want to disable ???????# ??keep-alive for those clients, too. Use variable "nokeepalive" for this. ???????# ??Similarly, one has to force some clients to use HTTP/1.0 to workaround ???????# ??their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and ???????# ??"force-response-1.0" for this. ???????# BrowserMatch "MSIE [2-6]" ????????# ??????nokeepalive ssl-unclean-shutdown ????????# ??????downgrade-1.0 force-response-1.0 ???</VirtualHost></IfModule># vim: syntax=apache ts=4 sw=4 sts=4 sr noet
启动ssl服务
a2ensite /etc/apache2/sites-available/lab-ssl.confa2enmod ssl
查看是否正确配置
在浏览器地址栏输入 https://localhost
发现浏览器不信任这个网站,为什么?行为这个网站的证书是用我们自己的CA签名的,浏览器并不信任我们自己建立的CA,所以我们需要手动导入CA证书让浏览器信任我们的CA。
导入步骤如下:
打开 FireFox 浏览器,依次选择“编辑”----“首选项”----“隐私与安全”----“证书”----“查看证书”----“证书机构”,点击导入,选择 myCA 目录下的根证书“cacert.pem”, 导入。
之后,再次浏览localhost
地址栏有一个绿色的锁,至此https服务搭建完成。
自建CA证书搭建https服务器
原文地址:http://www.cnblogs.com/libaoquan/p/7965873.html