# 前言

之前在 1panel 就看到可以申请 ECC 算法的 SSL 证书,目前也部分替换原来的 RSA 证书,但主要的泛域名证书还是 RSA。

虽然从表面上来看,ECC 的密钥长度和安全性在相同位数的安全等级下都优于 RSA,但从深层次来说,这里还有许多我们需要了解的知识。

事实上,ECC 算法下有很多种椭圆曲线,但是不同曲线的安全性,用途都是不相同的,使用不安全的曲线还不如使用 RSA 算法。

# 椭圆曲线

目前一般常见的曲线为下面几种:

  • Curve 25519
  • NIST 曲线
  • SM2 (国密)
  • brainpool

ECC 曲线汇总:https://safecurves.cr.yp.to/

# Curve 25519

Curve25519 是目前最高水平的 Diffie-Hellman 函数,适用于广泛的场景,由 Daniel J. Bernstein 教授设计。在密码学中,Curve25519 是一个椭圆曲线提供 128 位安全性,设计用于椭圆曲线 Diffie-Hellman(ECDH)密钥协商方案。它是最快的 ECC 曲线之一,并未被任何已知专利所涵盖[1]^{\left [ 1 \right ]}

有兴趣可以看一下

https://martin.kleppmann.com/papers/curve25519.pdf
https://cr.yp.to/ecdh.html

[1]:Curve25519 加密算法

# NIST 曲线

由美国政府制定的曲线。

  • P-192(scep192r1)
  • P-224(scep224r1)
  • P-256(scep256r1)
  • P-384(scep384r1)
  • P-521(scep521r1)

网上对于该系列曲线安全性有疑虑,怀疑有不为人知的后门。

其实也不奇怪,自从棱镜门事件后,美国在这方面就没啥可信度。

# SM2

我国推出的国密算法,但目前来说兼容性感人。

SM2 算法似乎遇到了类似的问题,就是部分参数在 SM2 规范里面没有给出令人信服的理由为什么这么选取[2]^{\left [ 2 \right ]}

[2]:https://www.cnblogs.com/byronsh/p/ecc-algorithm-security-and-selection.html

# brainpool

由欧洲推出的椭圆曲线,也具有安全风险[3]^{\left [ 3 \right ]},已被列为不安全。

[3]:https://safecurves.cr.yp.to/

# 签名算法

目前常见的签名方案有:

  • ECDSA (Elliptic Curve Digital Signature Algorithm)
  • EdDSA (Edwards-curve Digital Signature Algorithm)

以下介绍来自 ChatGPT

# ECDSA

基于椭圆曲线的数字签名算法,是一种用于生成和验证数字签名的算法。它使用椭圆曲线加密(ECC)和密码学原语来提供签名的安全性。

# 曲线

通常使用 NIST 提出的椭圆曲线(如 secp256r1、secp384r1)或其他 ECC 曲线。

# 安全性

安全性依赖于椭圆曲线的选择和参数设置。正确实现的情况下,它能提供与密钥长度相称的安全性。
可能受到一些攻击的威胁,如对特定曲线的攻击(例如,在椭圆曲线选择不当的情况下)。

# 性能

在生成和验证签名时的性能表现通常较好,但依赖于特定的曲线和实现。
签名生成速度可能相对较慢,尤其是在使用较长的密钥时。

# 实现复杂性

实现复杂,尤其是在确保防止常见漏洞(如侧信道攻击)时。
对于不经验丰富的实现者来说,确保 ECDSA 的安全性可能是一个挑战。

# EdDSA

基于 Edwards 曲线的数字签名算法,特别是 Curve25519 和 Ed448 曲线的变体。EdDSA 设计注重速度、简洁性和安全性。

# 曲线

主要使用 Edwards 曲线,如 Curve25519 和 Ed448。

# 安全性

设计时考虑了抗侧信道攻击的特性,更加防御针对实现细节的攻击。
使用 Curve25519 和 Ed448 曲线被认为是具有很高的安全性,并且其安全性与密钥长度成正比。

# 性能

设计时考虑了高性能和高效计算。EdDSA 通常在签名生成和验证时具有更高的效率。
Ed25519 在生成和验证签名时比 ECDSA 更快,且提供了更短的签名和密钥。

# 实现复杂性

实现通常更简单且容易验证,因为其设计中考虑了许多常见的实现问题。
设计上更为简洁,不容易出错,并且避免了一些 ECDSA 常见的陷阱。

Tips:Ed25519 是 EdDSA 签名算法的具体实现

# 密钥交换

一般来说,非对称加密效率低于对称加密。在实践中,一般采用通过交换对称加密密钥来进行通信加密,提高通信效率。

并且 ECDSA 和 EdDSA 只能用于签名,并不像 RSA 既可以用于签名也能用于加密。

常见有下面几种密钥交换协议:

  • ECDH
  • ECDHE
  • Authenticated DH
  • ECIES
  • RSA
  • DH

下面是 ChatGPT 对三者的比较

# DH (Diffie-Hellman)

基本概念:传统的 Diffie-Hellman 协议,用于在公共信道上安全地交换密钥。
优点

  • 安全性:理论上安全,只要离散对数问题难以解决。
  • 公开交换:不需要预先共享密钥。

缺点

  • 缺乏身份验证:容易受到中间人攻击(MITM)。
  • 性能开销:相对于某些现代协议,计算开销较大。

# Authenticated DH (Authenticated Diffie-Hellman)

基本概念:这是在传统 Diffie-Hellman 协议上添加身份验证机制的版本。它通过数字签名或证书来验证通信方的身份。
优点

  • 防中间人攻击:通过身份验证防止中间人攻击。
  • 安全性增强:提供比基础 Diffie-Hellman 更强的安全性。

缺点

  • 复杂性:身份验证过程增加了协议的复杂性。
  • 性能开销:身份验证增加了计算和通信开销。

# ECDH (Elliptic Curve Diffie-Hellman)

基本概念:ECDH 是椭圆曲线版本的 Diffie-Hellman 协议,用于生成共享密钥。
优点

  • 高效性:椭圆曲线提供高效的密钥交换,较短的密钥长度即可提供相同的安全性。
  • 前向保密:可通过 ECDHE 版本提供。

缺点

  • 曲线选择:需要选择合适的椭圆曲线,曲线选择不当可能影响安全性。
  • 实现难度:需正确实现曲线参数和密钥交换。

# ECDHE (Elliptic Curve Diffie-Hellman Ephemeral)

基本概念:ECDHE 是基于椭圆曲线的 Diffie-Hellman 协议的临时密钥版本。它用于生成临时密钥,用于加密会话密钥以增加安全性。
优点

  • 前向保密:由于使用临时密钥,每次会话的密钥都不同,即使长期密钥被泄露,过去的会话密钥仍然安全。
  • 效率高:椭圆曲线提供了高效的密钥交换。

缺点

  • 实现复杂性:需要正确实现临时密钥交换和密钥管理。

# ECIES (Elliptic Curve Integrated Encryption Scheme)

基本概念:ECIES 是一种综合加密方案,结合了椭圆曲线加密和对称加密,以实现密钥交换和数据加密。
优点

  • 综合性:结合了密钥交换和数据加密功能,效率高。
  • 安全性高:使用椭圆曲线提供的高效性和强大的加密安全性。

缺点

  • 实现复杂:需要同时处理公钥和对称密钥的加密和解密。
  • 协议开销:综合协议可能增加开销。

# RSA (Rivest-Shamir-Adleman)

基本概念:RSA 是一种公钥加密算法,既可用于密钥交换,也可用于加密和签名。
优点

  • 成熟稳定:广泛使用并经过长期验证。
  • 多功能:可用于加密和签名。

缺点

  • 性能问题:相对较慢,尤其在需要较长密钥时。
  • 密钥长度:为提供足够的安全性,需要较长的密钥。

# 总结

  • DH 是经典的密钥交换协议,简单但缺乏身份验证,容易受到 MITM 攻击。
  • ECDHEECDH 使用椭圆曲线,提供高效的密钥交换,并可通过临时密钥(ECDHE)增加前向保密。
  • Authenticated DH 增强了传统 DH 的安全性,通过身份验证防止攻击,但实现较复杂。
  • RSA 是成熟的公钥加密方案,适用于密钥交换、加密和签名,但性能较差。
  • ECIES 综合了密钥交换和加密功能,效率高但实现复杂。

# 具体流程

该流程由 ChatGPT 生成。

  1. 服务器证书:服务器使用包含 ECDSA 公钥的 ECC 证书来证明其身份。客户端通过验证服务器证书来确保连接到的是合法的服务器。

  2. 握手过程
    客户端 Hello:客户端发起 TLS 握手,包含支持的加密套件列表(包括支持的 ECDH 和 ECDSA 算法)、随机数等信息。
    服务器 Hello:服务器响应,选择一个合适的加密套件(如 ECDHE-ECDSA),并发送服务器的 ECDSA 公钥证书及一个随机数。

  3. 服务器 Key Exchange(如果需要)
    如果使用了 ECDHE(Ephemeral Elliptic Curve Diffie-Hellman),服务器会发送一个临时的 ECDH 公钥。

  4. 客户端 Key Exchange
    客户端生成一个临时的 ECDH 密钥对,并将临时公钥发送给服务器。

  5. 密钥交换
    双方通过各自的临时 ECDH 密钥对计算共享的对称密钥。
    客户端使用服务器的 ECDSA 证书验证服务器发送的公钥,确保中间人攻击不可行。

  6. Finished 消息
    双方使用生成的对称密钥加密并交换 “Finished” 消息,验证密钥交换和握手的完整性。

  7. 加密通信
    使用生成的对称密钥进行对称加密的数据传输,如 AES(Advanced Encryption Standard)。

简而言之,在 HTTPS 中,ECDSA 证书用于身份验证和签名,确保通信双方的合法身份。而实际的对称密钥交换则通过 ECDHE 协议完成,利用椭圆曲线 Diffie-Hellman 算法安全地交换对称加密密钥。这样,既能保证身份验证,又能安全高效地进行对称加密通信。

# 加密套件

通过 ChatGPT 的推荐以及综合自身实际情况,选择使用下方的加密套件:

1
EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AESGCM:EECDH+AES256:!MD5

使用 ECDHE 交换密钥,ECDSA/RSA 签名,CHACHA20/CHACHA20-draft/AES [128/256]-GCM/AES256-CBC 加密,SHA [256/384] 散列。

Tips:问了一下 ChatGPT 顺带查了一下资料,好像目前 NGINX 暂时不支持使用 EdDSA 进行密钥交换签名。

# 交换密钥

目前常用的 ECDHE 使用下面几种椭圆曲线 / 协议:

  • secp256r1(P-256)
  • secp384r1(P-384)
  • secp521r1(P-521)
  • X25519

secp 系列的安全问题就不说了,X25519 则是基于 Curve25519 的密钥交换协议

在 NGINX 中使用 ssl_ecdh_curve 指定 ECDHE 中使用的曲线 / 协议。

# 总结

ECC 证书的功能是确保在密钥交换环节不受到中间人攻击(普通的 DV 证书)

最终的数据加密取决于加密套件的设置以及与客户端的协商。

看了一下我的 ECC 证书,使用的签名算法是 ECDSA with SHA-384 ,希望哪天能快进到支持 EdDSA。。。

Curve25519 是目前最高水平的 Diffie-Hellman 函数(曲线)。

EdDSA 基于 Edwards 曲线的数字签名算法,特别是 Curve25519 和 Ed448 曲线的变体。

Ed25519 则是 EdDSA 签名算法的实现。

X25519 则是密钥交换协议,该协议基于 Curve25519 曲线

# 参考

Curve25519 加密算法
为什么汽车行业越来越倾向于 ECC 算法?
一文说明白 ECDSA secp256k1 secp256r1 EdDSA ed25519 千丝万缕的关系