HTTPS证书的申请、配置与验证流程
HTTPS 证书的申请
证书颁发机构(CA)的选择
在申请 HTTPS 证书之前,首先要选择一个合适的证书颁发机构(Certificate Authority,CA)。CA 是一个受信任的实体,负责验证网站所有者的身份,并颁发数字证书。常见的 CA 有 Let's Encrypt、Comodo、Symantec(现名为 DigiCert)、GlobalSign 等。
- Let's Encrypt:这是一个非营利性的 CA,提供免费的 HTTPS 证书,适合个人网站和小型企业使用。其优点是成本低,且通过自动化的流程可以方便快捷地获取证书。但免费证书的有效期较短,通常为 90 天,需要定期续签。
- 商业 CA:如 Comodo、Symantec 等,提供不同等级的证书,包括域名验证(Domain Validation,DV)证书、组织验证(Organization Validation,OV)证书和扩展验证(Extended Validation,EV)证书。商业 CA 的证书价格相对较高,但具有更高的信任度,有效期一般为 1 - 3 年。例如,EV 证书在浏览器地址栏会显示企业名称并以绿色高亮显示,增强用户对网站安全性的信心。
Let's Encrypt 证书申请流程
以 Let's Encrypt 为例,介绍证书的申请步骤。Let's Encrypt 支持多种方式获取证书,这里以 Certbot 工具为例,Certbot 是 Let's Encrypt 官方推荐的客户端,支持多种操作系统和 Web 服务器。
- 安装 Certbot:
- 在 Ubuntu 系统上:
sudo apt update sudo apt install certbot python3-certbot-nginx
- 在 CentOS 系统上:
sudo yum install epel - release sudo yum install certbot python3-certbot - nginx
- 在 Ubuntu 系统上:
- 申请证书:
假设你的网站域名为
example.com
,并且使用 Nginx 作为 Web 服务器。sudo certbot --nginx -d example.com -d www.example.com
上述命令中,--nginx
选项表示 Certbot 会自动检测并配置 Nginx 服务器,-d
选项用于指定要申请证书的域名,可以指定多个域名。运行该命令后,Certbot 会引导你完成一些配置步骤,例如输入邮箱地址(用于接收证书过期提醒等信息),同意服务条款等。
- 证书获取:
如果一切顺利,Certbot 会成功获取证书,并自动配置 Nginx 服务器使用该证书。证书文件通常会保存在
/etc/letsencrypt/live/example.com/
目录下,包含cert.pem
(证书文件)、privkey.pem
(私钥文件)和chain.pem
(证书链文件)等。
商业 CA 证书申请流程
商业 CA 的证书申请流程相对复杂一些,一般需要以下步骤:
-
准备资料:
- 对于 DV 证书,通常只需要提供域名信息和有效的邮箱地址。
- 对于 OV 和 EV 证书,除了域名信息外,还需要提供企业的相关证明文件,如营业执照副本、法人身份证明等,以验证企业的真实性和合法性。
-
提交申请: 访问所选商业 CA 的官方网站,按照其指引填写申请表格,上传相关资料。在填写申请表格时,需要准确填写域名、组织名称、联系人信息等内容。
-
验证身份: CA 会对提交的资料进行审核和身份验证。对于 DV 证书,一般通过发送验证邮件到域名的 WHOIS 信息中的邮箱地址,或者在网站根目录放置特定文件等方式进行验证。对于 OV 和 EV 证书,CA 可能会通过电话、邮件等方式与企业相关人员进行沟通,核实企业信息。
-
支付费用: 审核通过后,根据所选证书类型和有效期,在 CA 网站上完成费用支付。支付方式通常包括信用卡、PayPal 等。
-
获取证书: 支付完成后,CA 会颁发证书。你可以在 CA 网站的用户账户中下载证书文件,通常会包含证书文件(
.crt
或.cer
格式)、私钥文件(.key
格式)和证书链文件(.p7b
或.pem
格式等)。
HTTPS 证书的配置
在 Nginx 中配置 HTTPS 证书
-
找到 Nginx 配置文件: 在大多数 Linux 系统中,Nginx 的主配置文件位于
/etc/nginx/nginx.conf
,而虚拟主机的配置文件通常在/etc/nginx/sites - available/
目录下。假设你的虚拟主机配置文件为/etc/nginx/sites - available/example.com
。 -
编辑虚拟主机配置文件: 添加或修改以下内容,配置 HTTPS 服务器块:
server { listen 443 ssl; server_name example.com www.example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers HIGH:!aNULL:!MD5; location / { # 网站根目录和其他配置 root /var/www/html/example.com; index index.html index.php; try_files $uri $uri/ =404; } }
listen 443 ssl
:表示监听 443 端口,并启用 SSL/TLS 协议。server_name
:指定服务器的域名。ssl_certificate
:指定证书文件路径,对于 Let's Encrypt 证书,fullchain.pem
包含了证书和证书链。ssl_certificate_key
:指定私钥文件路径。ssl_protocols
:指定允许使用的 SSL/TLS 协议版本,TLSv1.2 和 TLSv1.3 是目前较为安全的版本。ssl_ciphers
:指定允许使用的加密套件,这里配置为只使用高强度加密套件,排除不安全的加密方式。
-
启用虚拟主机配置: 如果虚拟主机配置文件在
/etc/nginx/sites - available/
目录下,需要在/etc/nginx/sites - enabled/
目录下创建一个符号链接:sudo ln -s /etc/nginx/sites - available/example.com /etc/nginx/sites - enabled/
-
检查配置并重启 Nginx:
sudo nginx -t sudo systemctl restart nginx
nginx -t
命令用于检查 Nginx 配置文件是否有语法错误。如果没有错误,重启 Nginx 服务使配置生效。
在 Apache 中配置 HTTPS 证书
-
找到 Apache 配置文件: 在大多数 Linux 系统中,Apache 的主配置文件为
/etc/httpd/conf/httpd.conf
,虚拟主机的配置文件通常在/etc/httpd/conf.d/
目录下。假设你的虚拟主机配置文件为/etc/httpd/conf.d/example.com.conf
。 -
编辑虚拟主机配置文件: 添加或修改以下内容,配置 HTTPS 虚拟主机:
<VirtualHost *:443> ServerName example.com ServerAlias www.example.com DocumentRoot /var/www/html/example.com ErrorLog /var/log/httpd/example.com - error.log CustomLog /var/log/httpd/example.com - access.log combined SSLEngine on SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory /var/www/cgi - bin> SSLOptions +StdEnvVars </Directory> </VirtualHost>
ServerName
和ServerAlias
:指定服务器的域名。DocumentRoot
:指定网站根目录。SSLEngine on
:启用 SSL 引擎。SSLCertificateFile
:指定证书文件路径。SSLCertificateKeyFile
:指定私钥文件路径。SSLCertificateChainFile
:指定证书链文件路径。
-
检查配置并重启 Apache:
sudo httpd -t sudo systemctl restart httpd
httpd -t
命令用于检查 Apache 配置文件是否有语法错误。如果没有错误,重启 Apache 服务使配置生效。
在 Tomcat 中配置 HTTPS 证书
- 生成密钥库:
如果你的证书是由商业 CA 颁发的,通常会收到一个
.pfx
或.p12
格式的文件。可以使用以下命令将其转换为 Java 密钥库(.jks
)格式:keytool -importkeystore -srckeystore example.pfx -srcstoretype PKCS12 -destkeystore example.jks -deststoretype JKS
如果是 Let's Encrypt 证书,需要先将 cert.pem
、privkey.pem
和 chain.pem
合并为一个文件,例如 combined.pem
,然后使用以下命令生成密钥库:
openssl pkcs12 -export -in combined.pem -out example.p12 -name tomcat -CAfile chain.pem -caname root
keytool -importkeystore -srckeystore example.p12 -srcstoretype PKCS12 -destkeystore example.jks -deststoretype JKS
-
配置 Tomcat: 编辑 Tomcat 的
server.xml
文件,通常位于$CATALINA_HOME/conf/
目录下,添加或修改以下内容:<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443" maxThreads="200" scheme="https" secure="true" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateFile="conf/localhost.crt" certificateKeyFile="conf/localhost.key" type="RSA" /> </SSLHostConfig> </Connector>
port
:指定 HTTPS 监听端口,默认为 8443。scheme
和secure
:设置为https
和true
,表示启用 HTTPS。SSLEnabled
:启用 SSL。certificateFile
和certificateKeyFile
:指定证书文件和私钥文件路径。如果使用的是密钥库,则需要修改为:
<Connector protocol="org.apache.coyote.http11.Http11NioProtocol" port="8443" maxThreads="200" scheme="https" secure="true" SSLEnabled="true" keystoreFile="conf/your - keystore.jks" keystorePass="your - keystore - password" type="RSA" />
keystoreFile
:指定密钥库文件路径。keystorePass
:指定密钥库密码。
-
重启 Tomcat: 在
$CATALINA_HOME/bin/
目录下执行以下命令:sudo./shutdown.sh sudo./startup.sh
HTTPS 证书的验证
浏览器验证
最简单的验证方法是在浏览器中访问配置了 HTTPS 的网站。在现代浏览器中,如果证书配置正确且有效,地址栏会显示一个安全锁图标,点击该图标可以查看证书的详细信息,包括颁发机构、有效期、证书所有者等。
如果证书存在问题,浏览器会显示警告信息,例如:
- 证书过期:提示证书已过期,用户访问网站时会看到明显的警告,因为过期的证书无法保证通信的安全性。
- 证书不受信任:可能是由于使用了不受信任的 CA 颁发的证书,或者证书链不完整。这种情况下,浏览器可能会阻止用户访问,或者提示用户是否继续访问,存在一定的安全风险。
使用 OpenSSL 命令行工具验证
- 验证证书有效期:
可以使用以下命令查看证书的有效期:
openssl x509 -noout -dates -in /path/to/cert.pem
例如,对于 Let's Encrypt 证书:
openssl x509 -noout -dates -in /etc/letsencrypt/live/example.com/cert.pem
输出结果类似:
notBefore=Sep 15 10:20:40 2023 GMT
notAfter=Dec 14 10:20:40 2023 GMT
这表明证书的生效时间为 2023 年 9 月 15 日 10:20:40,过期时间为 2023 年 12 月 14 日 10:20:40。
- 验证证书链:
使用以下命令验证证书链的完整性:
openssl verify -CAfile /path/to/ca - bundle.pem /path/to/cert.pem
对于 Let's Encrypt 证书,可以使用其提供的证书链文件:
openssl verify -CAfile /etc/letsencrypt/archive/example.com/chain1.pem /etc/letsencrypt/live/example.com/cert.pem
如果证书链验证通过,会输出 cert.pem: OK
;如果验证失败,会显示相应的错误信息,如 error 20 at 0 depth lookup:unable to get local issuer certificate
,表示无法找到本地颁发者证书,可能是证书链不完整。
- 验证证书与域名的匹配:
可以通过解析证书中的 Subject Alternative Name(SAN)字段来验证证书是否与域名匹配。使用以下命令:
openssl x509 -noout -text -in /path/to/cert.pem | grep -A 1 'Subject Alternative Name'
例如:
openssl x509 -noout -text -in /etc/letsencrypt/live/example.com/cert.pem | grep -A 1 'Subject Alternative Name'
输出结果可能如下:
X509v3 Subject Alternative Name:
DNS:example.com, DNS:www.example.com
这表明证书的 SAN 字段包含了 example.com
和 www.example.com
,与配置的域名相匹配。如果域名不在 SAN 字段中,证书与域名不匹配,可能导致浏览器警告。
编写代码验证证书
以 Python 为例,可以使用 ssl
模块来验证证书。以下是一个简单的示例:
import socket
import ssl
def verify_certificate(host, port):
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations('/path/to/ca - bundle.pem')
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((host, port))
with context.wrap_socket(sock, server_hostname = host) as ssl_sock:
try:
cert = ssl_sock.getpeercert()
print('Certificate details:')
for key, value in cert.items():
print(f'{key}: {value}')
print('Certificate verification successful.')
except ssl.SSLError as e:
print(f'Certificate verification failed: {e}')
if __name__ == '__main__':
verify_certificate('example.com', 443)
在上述代码中:
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
:创建一个 SSL 上下文,指定使用 TLSv1.2 协议。context.verify_mode = ssl.CERT_REQUIRED
:设置验证模式为必须验证证书。context.load_verify_locations('/path/to/ca - bundle.pem')
:加载 CA 证书链文件用于验证。with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock
:创建一个 TCP 套接字。with context.wrap_socket(sock, server_hostname = host)
:将套接字包装为 SSL 套接字,并指定服务器主机名。cert = ssl_sock.getpeercert()
:获取服务器的证书。- 如果证书验证成功,打印证书详细信息并提示验证成功;如果验证失败,捕获
SSLError
并打印错误信息。
通过以上全面的申请、配置与验证流程,可以确保网站在 HTTPS 协议下安全可靠地运行,为用户提供加密的通信环境,保护用户数据和隐私。