密码学、SSL 和数字签名又一篇博客






4.84/5 (38投票s)
密码学、SSL 和数字签名的基础知识
引言
网上有数百万篇关于此的博文/教程,但我希望在这篇文章中尽可能简洁地解释我接下来的(安全相关)文章中会用到的概念。
我非常欢迎反馈和纠正(如有)。管理员/专家们,请随时纠正我的错误并提供宝贵的建议。
背景
虽然一些编程知识会有帮助,但理解本文并非必要。
哈希和填充
密码学哈希函数会生成一个输出值,这个值实际上不可能反向转换为原始输入值。最重要的是,即使输入值发生微小变化,生成的输出值也会发生剧烈变化。这种哈希函数涉及复杂的数学。
例如:
“Hello world” -------转换为------------> D8 A2 13 A1 98 93 8B F5.....
“Hello world.”-------转换为------------> C2 23 43 AA B2 49 8D E1....
MD5 和 SHA1/156 是流行的哈希算法(函数)。您可能不需要深入了解这些函数,但在大多数现代编程语言中,您会以某种形式找到它们的实现。
现代哈希算法以固定长度块处理消息,并将额外数据添加到这些消息块中,以使较短的消息块达到所需的尺寸。这被称为填充。
填充也是为了防止哈希函数的漏洞(如“长度扩展攻击”)。在这种情况下,会向输入附加一个固定字符串(读作:字节),使哈希更加复杂。在这种情况下,填充字符串也称为“Salt”。
那么,这一切如何帮助提高安全性与密码学呢?例如,想象一下,您将用户密码存储在数据库中时,存储的是实际密码的哈希值(而不是明文密码)。即使有人读取了数据库,用户的密码也不会泄露。然而,您的应用程序可以在用户登录屏幕上生成的密码哈希值,并将其与数据库密码哈希进行比较,从而验证用户。
在本篇及后续博文中,我们将大量引用“哈希”。
对称密钥密码学
对称密钥密码学在概念上很简单。使用一个数学“密钥”来加密消息,并使用相同的密钥来解密消息。密钥的复杂性和所用算法的复杂性直接影响消息被“破解”(解密)的难易程度。
对称密钥密码学相对较快(性能方面)。然而,传输和保管密钥可能成为一个相当大的问题,也是安全失败的单一原因。
AES(Rijndael)、Serpent 和 Twofish 是流行的对称密钥算法。
非对称密钥密码学
非对称密钥密码学有点复杂。它有一组密钥:**一个**“私钥”和**许多**“公钥”。然而,如果存在多个公钥,私钥的保密性就会受到损害。因此,在实际的非对称密钥加密中,通常只使用一个公钥对应一个私钥。请记住,这些密钥仅仅是数学值。然而,实际上它们是长而随机的**数字集合**,通常以十六进制表示。
公钥可以**加密**消息,但只有私钥才能**解密**它。同样,私钥也可以加密一个公钥可以解密的消息。然而,这种反向加密被称为“**签名**”和“**验证**”,而不是“加密”和“解密”,因为使用的算法不同。
DSA/DSS、RSA 和椭圆曲线是非对称密钥密码学中流行的算法。
什么是数字证书?
数字证书与非对称密钥密码学相关。它包含一些信息,包括(1)公钥值、(2)颁发者、(3)颁发给谁、(4)有效期,可能还包含(5)私钥值。公钥通常是一个很大的值,因此操作系统还会计算公钥的哈希值,并将其保存为证书的指纹(微软称之为指纹)。
数字证书可以是以文件的形式,或者保存在注册表中(在 MS-Windows 中)。如果数字证书是一个文件并且包含私钥,它可能还有密码保护。如果数字证书在注册表中(保存在证书存储中),操作系统会将相关的私钥单独保存为一个文件(我们将在本文后面讨论)。
Windows 操作系统有一个证书存储,它会将证书进行分类保存(安装)。要在 Windows 证书存储中查看已安装的证书:
- 开始 -> 运行 -> mmc ←
- 文件 -> 添加/删除管理单元…
- 从左侧面板选择“证书管理单元”并单击“添加”按钮。在提示时选择“本地计算机”选项。
- 在 mmc 控制台中,打开证书 -> 受信任的发布者 -> 证书。双击左侧的任何证书
证书可以有很多用途,例如(1)服务器身份验证(在 SSL 中)(2)客户端身份验证(3)代码签名(4)文档签名等。如果您右键单击证书存储中的证书并选择“属性”,“常规”选项卡将显示该证书的预期用途列表。
公钥基础设施 (PKI)
现在的问题是:谁颁发数字证书?答案是:证书颁发机构 (CA)。CA 可以是内部的(您的组织内)或外部的权威机构。CA 具有分层结构。这意味着有一些顶级 CA(如 Microsoft、Google 和 Verisign 等),以及由顶级 CA 授权颁发证书的多个中间 CA。这些 CA 被您的计算机“信任”。这种信任是通过您计算机上的“受信任的根证书颁发机构”、“企业信任”和“中间证书颁发机构”存储中存在的相关服务器证书(这些 CA 的公钥)建立的。您的操作系统预装了许多根证书,并通过安全更新不断更新这些证书。如果证书是由这些外部知名 CA 颁发的,您的证书将在世界各地都有效(因为知名 CA 是全球公认的)。这个由数字证书、证书颁发机构和信任组成的整个生态系统称为公钥基础设施 (PKI)。它已成为现代互联网和安全中一个最基本且不可分割的部分。
但是,CA 可以是您组织中的本地 CA 服务器。在这种情况下,它颁发的证书在您的组织外部将不被识别。但是,您的内部 CA 的服务器证书可以安装在外部计算机上(作为受信任的根/中间证书颁发机构),以信任此 CA 颁发的证书。
证书有一个到期日期,并且如果发生安全漏洞(例如,私钥被盗),也可以被吊销。在这种情况下,需要续订证书。另外请注意,如果证书颁发 CA 的根证书被吊销/过期,此 CA 颁发的所有证书都将被视为无效。CA 会维护一个证书吊销列表 (CRL),并在 SSL 握手(稍后解释)期间使用它来验证证书。
如果您想购买新的服务器证书(或续订它),正确的方法是创建一个 CSR(证书签名请求)并将其发送给证书颁发机构 (CA)。要生成 CSR,您首先需要创建一个公钥-私钥对,并将公钥嵌入 CSR 中。私钥**绝不**与任何人共享。即使是 CA 也不行。它是您/您组织的个人秘密。CSR 包括您的组织名称、地址和通用名称(您服务器的 FQDN)等其他详细信息。IIS 管理控制台或“Symantec SSL Assistant”(https://knowledge.symantec.com/support/ssl-certificates-support/index?page=content&id=AR235)等工具可以帮助您创建 CSR。证书(等待 CA 签名)将保存在您计算机的“证书注册请求”证书存储中,直到 CSR 被 CA 响应(正面)。CSR 响应的形式是一个 .cer 文件。您可以使用它来安装证书。(注意:如果在此过程中您的公钥与私钥意外断开连接,您可以使用管理员模式下的命令提示符中的“Certutil –repairstore”命令,使用证书指纹来修复链接。)
您还可以创建一个自签名证书。这只会在您的计算机上有效,并且在开发场景中有用。打开 IIS 管理控制台(我使用的是 IIS 7.5),单击顶级节点(显示您的服务器名称/计算机名称)并在“功能视图”面板中打开“服务器证书”。在左侧的“操作”面板中,您会看到几个创建证书请求的选项(如下图所示)。去探索一下这些选项,了解它们。Visual Studio 会创建自己的自签名证书(并负责信任它)。下图显示了这一点。
您还可以使用 OpenSSL/MakeCert 等工具生成证书,在您的开发环境中使用。网上有很多关于如何使用这些工具的教程。Fiddler 等工具也可以创建自己的证书(例如,用于 HTTPS 流量调试)。在所有情况下,请记住基本概念:要让计算机/用户信任证书,颁发者(或根颁发者)**必须**是受信任的。
当证书保存到文件时,文件可以是以下格式之一:
- .cer, .crt 或 .der:这些文件仅包含证书的公钥部分(和其他证书信息),但**不包含**私钥。这些文件可以是 Base64 编码的(包含在“-----BEGIN CERTIFICATE-----”和“-----END CERTIFICATE-----”字符串之间),或者 Distinguished Encoding Rules (DER) 编码的(限制只存储一个证书)。如果文件是 Base64 编码的,您可以在记事本中打开文件,看到整个证书作为一个编码字符串。注意:这不是指纹。指纹字符串要小得多,并且是证书的哈希值。
- .pfx(个人信息交换)或 .p12:包含私钥和其他扩展属性。这是**唯一**可以导出证书私钥的格式。
- .csr(证书签名请求):这是包含 CSR(如上所述)的编码格式的文件。数据包含在“-----BEGIN NEW CERTIFICATE REQUEST-----”和“-----END NEW CERTIFICATE REQUEST-----”之间。
- .crl(证书吊销列表):如前所述的证书吊销列表。
- .key:这只包含私钥。如果您使用 OpenSSL,可以看到这个文件。
- 还有其他鲜为人知的格式,如 .sst 和 .sto(微软专有)、.pem(更常用于 Unix 系统)、.p7b、.pp7r 和 .spc 等。
安全套接字层 (SSL)
SSL 代表安全套接字层。广义上说,它为互联网上的 HTTP 流量提供安全性。它是一个应用层协议(在 OSI 模型中)。它的新版本称为 TLS。SSL/TLS 使用底层的 SCHANNEL,它与传输层相关,并支持各种密码套件和加密等。SSL 1.0 从未在 www 上投入生产。然而,SSL 2.0 和 SSL 3.0 被广泛使用。从 SSL 3.1 开始,它就被称为 TLS。
SSL/TLS 提供 3 个非常重要的功能:隐私、身份验证和数据完整性。它使用安全隧道加密不安全的 HTTP 流量。结果协议称为“https”。它以 PKI 为核心。
在尝试理解 SSL 之前,让我们先了解一些重要的术语。
- 服务器证书:它是由知名 CA 颁发给**服务器**的数字证书(附带相关私钥)。其“颁发给”属性通常是网站的主机名(例如 blah.com)或通配符域名(例如 *.blah.com)。用于 SSL 的服务器证书必须存在于“本地计算机”账户的“个人”存储中。IIS 不会读取“用户”账户。证书必须标记为“服务器身份验证”,因为这是它的预期用途(使用其增强密钥用法属性)。此外,要与 SSL 一起使用,请确保应用程序池(用于网站)运行的用户帐户可以读取证书的私钥(可以通过右键单击证书 -> 所有任务 -> 管理私钥来检查)。
- 客户端证书:它是由 CA 颁发给**客户端**的数字证书(附带相关私钥)。这里的客户端可以是用户或客户端计算机。证书必须标记为“客户端身份验证”,因为这是它的预期用途。只有当 Web 应用程序/Web 服务配置了使用证书进行客户端身份验证时,才会使用此证书。
SSL 的详细内容超出了本文的范围,但以下图表将提供简要的理解。这里的“服务器”可以是运行在 Windows Server 上的 IIS,“客户端”可以是用户计算机上的浏览器。
显然,SSL 要复杂得多,但其本质是客户端使用服务器的公钥加密一个对称密钥,只有服务器才能解密。一旦 SSL 握手完成,所有后续通信都使用对称密钥加密。如果您问为什么不全程使用非对称密钥加密,答案是它很复杂,耗费时间和资源。因此,它的使用仅限于初始握手。
请注意,要成功进行 SSL 握手,客户端必须信任服务器的证书(或其颁发者的证书),并且证书必须有效。
让我们来看一些问题。
- 如果有人在中间监听整个通信怎么办?
他没有服务器的私钥。因此,他无法知道客户端发送了什么预共享密钥或之后的任何通信。
- 如果黑客冒充服务器并发送自己的自签名证书怎么办?
服务器发送的自签名证书将无法被客户端验证,并且用户将在浏览器(或任何客户端)中看到 SSL 错误消息。
- 如果黑客的根证书已经存在于用户的受信任证书存储中怎么办?
这可能是一个问题。但是,在用户计算机上安装证书需要管理员权限。此外,黑客无法从知名 CA 获取他未拥有的域(/网站)的服务器证书。
- 黑客如何能知道加密消息的内容,而只是不断重复服务器对客户端的响应或客户端对服务器的请求(即重放攻击)?
SSL 使用“消息认证码”(MAC)来保证数据完整性。MAC 是正在发送的消息的哈希值,以及序列号、消息长度和两个固定的字符字符串。有关更多详细信息,请阅读此内容(https://technet.microsoft.com/en-au/library/cc783349%28v=ws.10%29.aspx?f=255&MSPPError=-2147217396#w2k3tr_schan_how_hkrr)。
这种机制确保即使执行了重放攻击,服务器和/或客户端也会拒绝该数据包。
- 黑客是否有可能猜出服务器的私钥或 SSL 握手后使用的对称密钥?
数学上是可能的,但实际上并非如此。密钥通常非常复杂且很长,即使使用最新的 IT 基础设施,黑客也需要花费大量时间才能找出它。
- 如果一个(知名)根 CA 被攻破怎么办?
那么世界将陷入大麻烦 J。但这永远不会发生。根 CA 具有最高级别的安全(和审计)措施。假设发生这种情况,Microsoft 将发布一个安全更新,该更新将撤销用户计算机上被攻破 CA 的根证书,导致 SSL 失败。提示:保持您的操作系统更新到最新的关键安全更新。
- 这是否意味着 SSL 永远不会被破解?
确实出现过旧版 SSL 漏洞被识别的情况(例如,“Poodle”漏洞)。但是,技术栈已更新以解决这些问题。
- SSL 是否会加密图片、CSS、JavaScript 和 Cookie 等?
是的,它会。但是,如果您通过绝对链接在 HTML 中提供图片/CSS/JavaScript,并且这些链接是 http(在一个 https 网页上),那么就会有问题。不同的浏览器处理此问题的方式似乎不同。例如,Chrome 会显示以下错误消息(通过开发者工具看到):net::ERR_INSECURE_RESPONSE。
但是,IE 会显示以下内容:
图:IE SSL 错误
您的整个网站(如果它是网站)**必须**完全使用 https。在 https 通道上提供的任何非 http 内容都是安全漏洞。同样,理想情况下,请确保您所有的 Cookie 都安全地保存在客户端计算机上(已加密)。
数字签名
使用数字签名的三个主要原因是:身份验证、完整性和不可否认性。
还记得我之前提到的,私钥可以加密(签名)消息,而相关的公钥可以解密(验证)吗?因此,如果服务器发送带有数字签名的消息,客户端可以解密它,并确保消息确实来自服务器。这是数字签名的“身份验证”功能。
在此基础上,让我们假设服务器对它发送的整个消息进行哈希,并用私钥对哈希进行签名。当客户端收到数字签名(以及实际消息)时,它可以解密它并获取哈希值。然后,它可以生成消息本身的哈希值,并将生成的哈希值与服务器发送的哈希值进行比较。这一切可以实现什么?:确保消息未被篡改,并且仅由服务器发送。这是数字签名的“完整性”功能。
数字签名算法还会给消息打上时间戳,这意味着消息保证是在给定时间(由发件人)发送的。这是数字签名的“不可否认性”功能。将其与纸质文件的手动签名进行比较。我们签署并注明日期是为了承认我们在给定日期(和时间)验证了该文件。
请注意,用于 SSL 的同一数字证书不应用于签名,因为 SSL(加密)的目的与数字签名(身份验证、完整性和不可否认性)不同。将两者在功能和逻辑上分开是最佳实践。
关注点
希望您喜欢这篇文章。请留下您的反馈和评论。更多内容即将推出…