HTTPS、TLS/SSL的基本概念

HTTPS(HyperText Transfer Protocol Secure)是HTTP协议的安全版。它通过加密来确保数据在客户端和服务器之间传输时不会被窃取或篡改。
TLS/SSL是用于实现HTTPS的加密协议。SSL(Secure Sockets Layer)是最早的版本,后来被TLS(Transport Layer Security)取代,后者更安全和现代化。

证书与密钥的基本原理

在HTTPS中,有两个核心概念:公钥加密和证书。

公钥加密:

类比:想象你有一个密码箱,这个箱子有两把钥匙:公钥和私钥。公钥像是只负责锁上箱子的钥匙,任何人都可以得到一把公钥来锁上你的箱子,但只有你持有的那把私钥可以打开这个箱子。
在HTTPS中,公钥用来加密数据,而私钥用来解密数据。

证书:

类比:假设你去某个银行开设账户(比如申请一个公钥),银行会给你一个带有公章的证明文件,这证明你确实是你,并且你申请的账户(公钥)确实属于你。这个证明文件在HTTPS中就是证书。
证书由证书颁发机构(CA,Certificate Authority)签发,它可以验证你的公钥确实属于你,从而防止中间人冒充你进行攻击。

常见的文件类型及其作用

.pem 文件:

PEM(Privacy Enhanced Mail)是一个容器格式,用来保存多种不同的加密数据,如证书、公钥、私钥等。
类比:.pem文件像是一个带分隔符的大信封,里面可以装各种各样的信件(加密数据)。

.crt 文件:

.crt文件通常包含证书(Certificate)。它是公钥和一些身份信息的组合,经过证书颁发机构(CA)的签名,证明这个公钥确实属于特定的持有者。
类比:.crt文件就像银行给你开具的公章证明,证明某个公钥确实属于你。

.key 文件:

.key文件包含私钥。这是你用来解密信息的“钥匙”,必须严格保密。
类比:.key文件就像你自己保管的那把可以打开密码箱的钥匙。

.csr 文件:

CSR(Certificate Signing Request)是证书签名请求。当你想从CA获得一个证书时,首先生成一个CSR文件,其中包含你的公钥和一些身份信息,然后提交给CA,CA审核通过后会签发给你一个正式的证书。
类比:.csr文件就像你去银行申请账户时填写的申请表,表格中包括你的基本信息和你想要的账户信息(公钥),银行(CA)审核后会给你正式的账户文件(证书)。

证书和密钥的交互工作原理

当你访问一个使用HTTPS的网站时,整个过程大致如下:

  1. 客户端发起请求:你的浏览器向服务器请求一个安全连接。
  2. 服务器响应:服务器会将它的公钥证书(.crt文件)发送给浏览器。
  3. 验证证书:浏览器使用内置的受信任CA列表验证服务器证书的有效性,确保它是由可信的CA签发的。
  4. 生成会话密钥:浏览器生成一个临时的会话密钥,并使用服务器的公钥对它进行加密。
  5. 密钥交换:加密后的会话密钥发送给服务器,服务器用它的私钥(.key文件)解密出会话密钥。
  6. 加密通信:此后,双方使用这个会话密钥进行加密通信。

    总结

    .pem文件:通用容器,可包含证书、私钥、公钥等。
    .crt文件:包含经过CA签名的证书,证明某个公钥的身份信息。
    .key文件:私钥,用于解密信息。
    .csr文件:证书签名请求,包含生成证书所需的公钥和身份信息。

    自签证书

    什么是自签证书?

    自签证书(Self-Signed Certificate)是一种由自己签发的证书,而不是由第三方证书颁发机构(CA)签发的证书。换句话说,你自己扮演了CA的角色,自己生成公钥和私钥,然后用自己的私钥来对这个证书进行签名。

类比:
想象你在家中组织了一场派对,作为主人,你为自己制作了一张“最佳派对组织者”奖状并签了名。这张奖状上确实证明了你是这场派对的组织者,但因为是你自己签的名,其他人可能会质疑这个奖状的权威性。

自签证书的生成

生成自签证书的过程大致如下:

生成私钥:首先,生成一个私钥。这就像是你制作了一把专门用来解锁的钥匙,这把钥匙必须严格保密。

生成公钥:接下来,生成与该私钥对应的公钥。这把公钥可以公开,它会用于加密信息。

创建证书签名请求(CSR):这个步骤通常在请求CA签发证书时使用,但是在自签证书中,这一步可以略过。CSR文件中包含了公钥和一些其他信息。

生成证书并自签名:最后,使用你的私钥对包含公钥的信息进行签名,从而生成自签证书。

自签证书的使用场景

自签证书最常见的使用场景包括:

开发和测试环境:在开发和测试阶段,你可以使用自签证书来加密内部流量,而不需要购买正式的CA签发的证书。这可以节省成本并简化流程。

内部网络:在某些公司或组织内部,如果网络是封闭的且不对外开放,他们可能使用自签证书来加密内部通信,因为外部的信任链不是必须的。

教育目的:在学习和研究加密技术的过程中,自签证书是一个很好的实践工具,允许你深入了解证书的工作机制。

自签证书的缺点

尽管自签证书有它的用途,但它也有一些显著的缺点:

不被浏览器信任:因为自签证书没有经过CA的认证,绝大多数浏览器都会把它标记为不安全,并弹出警告。这是因为浏览器无法确认这个证书的真实性——它无法信任你自己签发的“奖状”。

缺乏信任链:CA签发的证书建立在一个信任链的基础上,而自签证书没有这样的信任链。如果没有手动添加信任,其他系统和用户也不会信任自签证书。

不能用于公开的生产环境:由于浏览器不信任自签证书,因此它们不适合在公开的生产环境中使用。如果你的网站面向公众,自签证书可能会吓跑用户,因为浏览器会显示安全警告。

自签证书 vs CA签发证书

信任来源:CA签发的证书是由受信任的第三方(CA)验证并签署的,具有广泛的信任基础。而自签证书仅由自己签署,没有外部的信任来源。

使用场景:CA签发的证书适用于需要广泛信任的公开环境(如在线商店、企业网站)。自签证书适用于内部或开发测试环境。

成本:CA签发的证书通常需要支付费用,而自签证书是免费的,因为你自己生成和签署了它。

总结

自签证书是一个非常有用的工具,尤其是在内部开发或测试环境中。它允许你在不依赖外部CA的情况下进行加密通信,但由于缺乏广泛的信任基础,它不适合用于需要公众信任的场合。在实际使用中,如果要部署一个公开访问的网站,最好还是使用CA签发的证书。

实践

/etc/ssl/certs/

在容器或一般的Linux系统中,/etc/ssl/certs/目录通常存放的是系统信任的CA证书,即由各种证书颁发机构(CA)签发的根证书和中间证书。这些证书被系统和应用程序用来验证其他证书的真实性和有效性。

/etc/ssl/certs/目录的内容

  • 根证书(Root Certificate):这是由根证书颁发机构(Root CA)签发的证书。根CA是信任链的起点,它们的证书自签名,即由CA自己签发和认证。操作系统和浏览器通常内置一组被广泛信任的根证书。

  • 中间证书(Intermediate Certificate):这些是由根CA签发给中间CA的证书,中间CA进一步签发给最终用户(比如网站)的证书。这种层次结构称为证书链。中间证书提高了安全性,因为即使中间CA的证书被盗用,根CA的证书仍然是安全的。

  • 符号链接或哈希文件:有时,这个目录中会包含指向实际证书文件的符号链接,这些链接的名字是证书的哈希值(通常使用OpenSSL工具生成)。这些链接帮助系统快速查找和验证证书。

    SAN

    在数字证书中,IP地址可以包含在证书的Subject Alternative Name (SAN) 字段中。SAN字段是证书中的一个扩展,用来指定多个备用的名称或标识符,这些标识符可以是域名(如example.com)、IP地址(如192.168.1.1)、邮箱地址等。

Subject Alternative Name (SAN) 字段

SAN字段允许证书支持多个标识符,这对于现代网络中的应用场景非常有用。以下是SAN字段中可以包含的一些常见类型:

DNS名称(Domain Name System Name):用于域名,如www.example.com。这是最常见的用法,尤其是在网站证书中。
IP地址(IP Address):可以是IPv4或IPv6地址,例如192.168.1.1或2001:0db8::1。
邮箱地址(Email Address):如admin@example.com。
URI(Uniform Resource Identifier):如http://example.com/some/path。

为什么在证书中包含IP地址?

在某些情况下,使用IP地址而非域名进行通信是有必要的,特别是在没有域名或域名解析不方便的环境下。以下是一些需要在证书中包含IP地址的典型场景:

内网服务器:在内网中,有些服务器可能只通过IP地址访问。这种情况下,证书需要包含这些IP地址,以便客户端可以验证服务器的身份。

开发和测试环境:在某些开发或测试场景下,使用IP地址而不是域名更为常见,因此证书中需要包括相应的IP地址。

专用设备或物联网(IoT)设备:这些设备可能通过IP地址直接连接,而不依赖域名系统(DNS)。

IP地址与域名的区别

值得注意的是,证书中通常更常见的是域名,而不是IP地址。这是因为域名可以映射到不同的IP地址(负载均衡、容灾等场景),而且更容易管理。然而,在一些特定场景下,直接使用IP地址是必要的,因此证书中包含IP地址也很常见。

最佳实践

1
2
openssl req -new -nodes -keyout server.key -out server.csr -config openssl.cnf
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt -extensions v3_req -extfile openssl.cnf

这个命令实际上包含了两部分,每部分都是使用 OpenSSL 工具来生成和签署证书的步骤。让我们逐一解析这些命令的含义。

第一部分:生成私钥和证书签名请求(CSR)

1
openssl req -new -nodes -keyout server.key -out server.csr -config openssl.cnf

解析:

  • openssl req:这个命令用于生成一个证书签名请求(CSR)或自签名证书。这里选择生成CSR。

  • -new:表示生成一个新的证书签名请求(CSR)。

  • -nodes:指“不加密私钥”。通常情况下,生成的私钥文件会被加密并要求你提供一个密码来解密使用,但使用-nodes选项后,私钥将以明文形式存储,不需要密码保护。

  • -keyout server.key:指定生成的私钥文件名为server.key,并将其输出到当前目录。

  • -out server.csr:指定生成的证书签名请求(CSR)文件名为server.csr,并将其输出到当前目录。

  • -config openssl.cnf:指定配置文件openssl.cnf,该文件包含了生成CSR所需的详细信息,如证书的主题(Subject)信息、扩展信息等。

总结:

这一部分的命令生成了一个明文的私钥server.key和一个证书签名请求server.csr,CSR中包含了公钥和证书的基本信息。

第二部分:自签名生成证书

1
openssl x509 -req -days 3650 -in server.csr -signkey server.key -out server.crt -extensions v3_req -extfile openssl.cnf

解析:

  • openssl x509:这个命令用于管理X.509证书。可以用来查看、转换、签署证书等操作。

  • -req:表示输入的内容是一个证书签名请求(CSR),即通过-in选项指定的文件。

  • -days 3650:指定生成的证书有效期为3650天(大约10年)。这个选项设置了证书的到期时间。

  • -in server.csr:指定输入的CSR文件为server.csr。这个CSR包含了证书的基本信息和公钥。

  • -signkey server.key:使用server.key文件中的私钥对证书进行自签名。自签名意味着这张证书是由自己签发和签名的,没有通过第三方证书颁发机构(CA)。

  • -out server.crt:指定生成的自签名证书文件名为server.crt,并将其输出到当前目录。

  • -extensions v3_req:指定启用openssl.cnf配置文件中v3_req部分定义的扩展字段。这通常用于定义扩展的证书属性,比如Subject Alternative Name (SAN)。

  • -extfile openssl.cnf:指定要读取的扩展配置文件为openssl.cnf,它包含了v3_req扩展的具体配置。

总结:

这一部分的命令使用前面生成的server.key私钥对server.csr进行自签名,生成一个自签名证书server.crt。证书的有效期为3650天,并且从openssl.cnf文件中读取扩展配置。

全流程总结

  1. 生成私钥和CSR:首先,命令生成了一个明文的私钥(server.key)和一个包含证书请求信息的CSR文件(server.csr)。CSR文件中包含了待生成证书的公钥和其他信息。

  2. 自签名生成证书:接着,使用生成的私钥(server.key)对CSR文件(server.csr)进行自签名,创建了一个有效期为10年的自签名证书(server.crt)。该证书包含了一些在配置文件中定义的扩展信息。

  3. 将生成的自签名证书拷贝到受信任的证书存储位置,如/etc/ssl/certs/,以便系统和应用程序可以信任和使用这张证书。