公开文集
0x01 SRC 资产管理系统
0x02 Web 漏洞案例库
0x03 小程序漏洞案例库
第一章:小程序渗透基础
1.1 微信小程序反编译与动态调试
1.2 微信小程序强制开启开发者模式
0x99 信息安全学习体系
01-网络安全基础
Day-001-TCP-IP协议栈安全分析
Day-002-DNS协议安全与DNS劫持攻防
Day-003-IPv6 安全基础与过渡
Day-004-HTTP-HTTPS协议深度解析
Day-005-网络嗅探与流量分析技术
Day-006-防火墙原理与配置实践
Day-007-网络地址转换 NAT 安全分析
Day-008-路由协议安全 RIP-OSPF-BGP
Day-009-VLAN 安全与 VLAN-Hopping
Day-010-无线网络基础与安全 802.11
Day-011-网络访问控制 802.1X-NAC
Day-012-网络分段与微隔离设计
Day-013-负载均衡器安全配置
Day-014-CDN安全与防护
Day-015-NTP安全
Day-016-DHCP安全与攻击防护
Day-017-ICMP协议安全分析
Day-018-网络协议模糊测试基础
Day-019-网络流量基线建立
Day-020-网络取证基础
Day-021-网络入侵检测系统 NIDS
Day-022-网络入侵防御系统 NIPS
Day-023-网络流量加密与解密
Day-024-网络协议逆向工程基础
Day-025-网络性能与安全权衡
Day-026-SDN 安全
Day-027-网络虚拟化安全
Day-028-网络欺骗技术
Day-029-网络威胁情报应用
Day-030-网络容量规划与安全
Day-031-网络安全架构设计实战
02-Web 安全
Day-032-OWASP-Top-10-2021详解
Day-033-SQL 注入原理与手工检测
Day-034-SQL注入进阶报错注入与盲注
Day-035-XSS跨站脚本攻击基础
Day-036-XSS 进阶绕过与利用
Day-037-XSS进阶绕过与利用
Day-038-CSRF 跨站请求伪造
Day-039-文件上传漏洞
Day-040-反序列化漏洞基础
Day-041-PHP反序列化深入
Day-042-Java反序列化深入
Day-043-SSTI 服务端模板注入
Day-044-文件包含漏洞 LFI-RFI
Day-045-命令注入漏洞
Day-046-XXE-XML 外部实体注入
Day-047-反序列化漏洞进阶
Day-048-API 安全基础
Day-049-API认证与授权安全
Day-050-API漏洞挖掘实战
Day-051-文件上传漏洞进阶
Day-052-反序列化漏洞实战
Day-053-Web 安全综合实战
Day-054-移动安全基础
Day-055-Android 应用安全测试
Day-056-iOS 应用安全测试
Day-057-移动应用综合实战
Day-058-云安全基础
Day-059-AWS 安全实战
Day-060-Azure 安全实战
Day-061-GCP 安全实战
Day-062-云安全综合实战
Day-063-容器安全基础
Day-064-Docker 安全实战
Day-065-Kubernetes 安全实战
Day-066-容器安全综合实战
Day-067-API 安全进阶
Day-068-服务端请求伪造 SSRF 深入
Day-069-文件上传漏洞进阶
Day-070-反序列化漏洞实战进阶
Day-071-业务逻辑漏洞深入
Day-072-前端安全深入
Day-073-Web 安全综合实战
Day-074-云安全进阶
Day-075-移动安全进阶
Day-076-API 安全进阶
Day-077-前端安全进阶
Day-078-业务逻辑漏洞进阶
Day-079-反序列化漏洞实战进阶
Day-080-文件上传漏洞实战进阶
Day-081-SSTI 服务端模板注入进阶
Day-082-XXE-XML 外部实体注入进阶
Day-083-SSRF 服务端请求伪造进阶
Day-084-命令注入漏洞进阶
Day-085-文件包含漏洞进阶
Day-086-反序列化漏洞实战进阶
Day-087-文件上传漏洞实战进阶
Day-088-SSTI 服务端模板注入实战进阶
Day-089-XXE-XML 外部实体注入实战进阶
Day-090-SSRF 服务端请求伪造实战进阶
Day-091-命令注入漏洞实战进阶
Day-092-Web 安全综合实战
Day-093-GraphQL 安全
Day-094-JWT 与 OAuth2 安全
03-系统安全
Day-095-系统监控与检测
Day-096-主机防火墙配置
Day-097-系统审计与合规
Day-098-Linux 系统安全进阶
Day-099-Windows 系统安全进阶
Day-100-容器安全进阶
Day-101-容器编排安全进阶
Day-102-Linux 内核安全
Day-103-Windows 内核安全
Day-104-系统安全总结与实战
Day-105-Linux 系统安全基础
Day-106-Windows 系统安全基础
Day-107-容器安全基础
Day-108-系统加固技术
Day-109-日志分析技术
Day-110-威胁狩猎技术
04-应用安全
Day-111-安全编码规范
Day-112-输入验证技术
Day-113-输出编码技术
Day-114-错误处理安全
Day-115-会话管理安全
Day-116-认证安全
Day-117-授权安全
Day-118-数据保护安全
Day-119-日志安全
Day-120-API 安全
Day-121-微服务安全
Day-122-新兴技术安全概论
Day-123-DevSecOps 流水线安全
Day-124-云原生安全架构
Day-125-API 安全最佳实践
Day-126-安全编码规范
Day-127-SDL 安全开发生命周期
Day-128-威胁建模实战
Day-129-安全需求分析
Day-130-安全架构设计
Day-131-安全编码实践Java
Day-132-安全编码实践Python
Day-133-代码审计方法论
Day-134-静态代码分析SAST
Day-135-动态应用测试DAST
Day-136-交互式测试IAST
Day-137-软件成分分析SCA
Day-138-依赖漏洞管理
Day-139-安全测试自动化
Day-140-漏洞管理与响应
Day-141-应用安全总结与展望
Day-142-OWASP-Top10-2024 详解
Day-143-CWE-Top25 分析
Day-144-漏洞挖掘方法论
Day-145-模糊测试技术
Day-146-逆向工程基础
Day-147-漏洞利用开发基础
Day-148-漏洞复现与验证
Day-149-漏洞披露流程
Day-150-CVE 申请与管理
Day-151-漏洞赏金计划
Day-152-等保2.0详解
Day-153-GDPR 合规实践
Day-154-数据安全法解读
Day-155-个人信息保护法与合规指南
Day-156-个人信息保护法解读
Day-157-ISO-27001 信息安全管理体系
Day-158-SOC-2 合规与审计
Day-159-PCI-DSS 支付卡行业数据安全标准
Day-160-网络安全审查办法解读
Day-161-数据出境安全评估办法
Day-162-应用安全评估实战
Day-163-红蓝对抗演练
Day-164-安全应急响应
Day-165-安全运营中心建设
Day-166-应用安全总结与展望
05-密码学
Day-167-密码学基础
Day-168-对称加密算法详解
Day-169-非对称加密算法详解
Day-170-哈希函数与数字签名
Day-171-密钥管理与PKI
Day-172-TLS-SSL 协议详解
Day-173-国密算法详解
Day-174-认证与密钥协议
Day-175-随机数生成与熵源
Day-176-椭圆曲线密码学详解
Day-177-后量子密码学详解
Day-178-高级密码学主题
Day-179-密码学行业应用精选
Day-180-常用加密算法原理与实现
Day-181-密码学总结与展望
Day-182-密码学系列总结与展望
06-渗透测试
Day-183-渗透测试方法论
Day-184-信息收集技术详解
Day-185-漏洞扫描技术详解
Day-186-漏洞利用技术详解
Day-187-渗透测试中的漏洞利用框架
Day-188-漏洞利用框架与 Metasploit 深入
Day-189-渗透测试中的 WAF 绕过技术
Day-190-渗透测试中的模糊测试技术
Day-191-渗透测试中的代码审计与静态分析
Day-192-渗透测试中的密码哈希破解技术
Day-193-渗透测试报告编写指南
Day-194-Web 应用渗透测试
Day-195-渗透测试中的 API 安全测试
Day-196-渗透测试中的 GraphQL 安全测试
Day-197-渗透测试中的前后端分离应用测试
Day-198-渗透测试中的小程序安全测试
Day-199-渗透测试中的浏览器安全测试
Day-200-OAuth-SSO安全测试
Day-201-渗透测试中的业务逻辑漏洞测试
Day-202-渗透测试中的厚客户端安全测试
Day-203-渗透测试综合实战演练
Day-204-内网渗透技术详解
Day-205-渗透测试中的内网信息收集进阶
Day-206-渗透测试中的域森林渗透技术
Day-207-渗透测试中的权限维持技术
Day-208-渗透测试中的横向移动技术
Day-209-渗透测试中的痕迹清理与反取证技术
Day-210-渗透测试中的数据窃取与 Exfiltration 技术
Day-211-渗透测试中的内部威胁与数据泄露测试
Day-212-渗透测试中的物理安全渗透
Day-213-社会工程学攻击技术
Day-214-移动应用渗透测试
Day-215-云安全渗透测试
Day-216-渗透测试中的容器与 Kubernetes 安全渗透
Day-217-渗透测试中的 Serverless 安全测试
Day-218-渗透测试中的微服务安全测试
Day-219-物联网安全渗透测试
Day-220-工业控制系统安全渗透测试
Day-221-无线网络安全渗透测试
Day-222-数据库安全渗透测试
Day-223-渗透测试中的供应链安全测试
Day-224-红队演练技术详解
Day-225-渗透测试中的红队基础设施搭建
Day-226-渗透测试中的威胁情报与狩猎
Day-227-渗透测试中的综合指纹识别技术
Day-228-自动化渗透测试技术
Day-229-渗透测试中的运维安全测试
Day-230-渗透测试中的区块链与智能合约安全测试
Day-231-渗透测试中的漏洞管理与修复验证
Day-232-渗透测试法律与合规
Day-233-后渗透攻击技术详解
Day-234-渗透测试中的人工智能应用
Day-235-漏洞利用开发深入
Day-236-云原生渗透测试深入
07-应急响应
Day-237-应急响应概述与核心概念
Day-238-应急响应流程框架
Day-239-CSIRT 团队组建与职责分工
Day-240-应急响应工具包准备
Day-241-应急响应法律与合规要求
Day-242-安全事件检测方法与指标
Day-243-云原生应急响应
Day-244-日志收集与分析技术
Day-245-网络流量分析与异常识别
Day-246-自动化响应与 SOAR
Day-247-端点监控与 EDR 技术
Day-248-威胁狩猎方法论
Day-249-威胁情报在检测中的应用
Day-250-数字取证基础与证据链管理
Day-251-内存取证技术
Day-252-磁盘取证与文件恢复
Day-253-网络取证与数据包分析
Day-254-云环境与容器取证
Day-255-恶意代码静态分析技术
Day-256-恶意代码动态分析技术
Day-257-恶意代码行为分析方法
Day-258-逆向工程基础与工具
Day-259-沙箱技术与自动化分析
Day-260-事件隔离与遏制策略
Day-261-威胁根除与系统修复
Day-262-系统恢复与数据重建
Day-263-业务连续性计划
Day-264-事件复盘与经验总结
Day-265-APT 攻击事件复盘分析
Day-266-勒索软件事件响应实战
Day-267-数据泄露事件处置流程
Day-268-内部威胁调查与取证
Day-269-综合应急响应演练
08-安全运维
Day-270-安全运营中心 SOC 概述
Day-271-安全监控指标体系
Day-272-安全告警管理
Day-273-安全可视化与仪表盘
Day-274-监控工具选型
Day-275-日志采集技术
Day-276-日志标准化与解析
Day-277-日志存储与归档
Day-278-日志分析技术
Day-279-日志合规要求
Day-280-SIEM 架构与设计
Day-281-关联规则引擎
Day-282-高级关联分析
Day-283-UEBA 用户实体行为分析
Day-284-威胁狩猎
Day-285-SOAR 基础概念
Day-286-剧本设计
Day-287-自动化响应技术
Day-288-安全工具集成
Day-289-SOAR 度量与优化
Day-290-安全基线管理
Day-291-漏洞管理流程
Day-292-补丁管理策略
Day-293-变更安全管理
Day-294-合规审计技术
Day-295-7x24 安全运营
Day-296-安全事件管理流程
Day-297-安全运营度量体系
Day-298-持续改进机制
Day-299-安全运维综合演练
Day-300-云原生安全运营
Day-301-AI 与机器学习安全运营
Day-302-安全自动化脚本实战
09-移动安全
Day-303-移动安全威胁概述
Day-304-移动设备安全架构
Day-305-移动操作系统安全模型
Day-306-移动应用权限管理
Day-307-移动端数据加密
Day-308-330-Android 安全合集
Day-309-Android 安全架构
Day-310-Android 组件安全
Day-311-Android 权限与隐私
Day-312-Android 逆向工程
Day-313-Android 应用加固
Day-314-iOS 安全架构
Day-315-iOS 应用沙盒机制
Day-316-越狱与反越狱
Day-317-iOS 逆向工程
Day-318-iOS 企业分发安全
Day-319-移动安全开发生命周期
Day-320-移动应用安全测试
Day-321-移动应用加固技术
Day-322-移动威胁防护
Day-323-移动安全合规
10-云安全
Day-324-云计算安全模型
Day-325-责任共担模型
Day-326-云安全威胁模型
Day-327-云安全合规框架
Day-328-云安全架构设计
Day-329-AWS IAM 安全
Day-330-AWS 网络安全
Day-331-AWS 存储安全
Day-332-AWS 安全监控
Day-333-AWS 安全最佳实践
Day-334-Azure AD 安全
Day-335-Azure 网络安全
Day-336-Azure 存储安全
Day-337-Azure 安全中心
Day-338-Azure 安全最佳实践
Day-339-容器安全基础
Day-340-Kubernetes 安全
Day-341-Serverless 安全
Day-342-云原生 DevSecOps
Day-343-云安全态势管理 CSPM
11-物联网工控
Day-344-物联网安全概述
Day-345-IoT 通信协议安全
Day-346-IoT 设备安全
Day-347-IoT 平台安全
Day-348-IoT 应用安全
Day-349-工业控制系统概述
Day-350-工控协议安全
Day-351-PLC 安全
Day-352-SCADA 系统安全
Day-353-工控安全防护
12-综合与总结
Day-354-安全职业发展路径
Day-355-安全技术趋势展望
Day-356-安全建设方法论
Day-357-经典攻防案例复盘
Day-358-安全学习资源指南
Day-359-信息安全行业求职指南
-
+
首页
Day-176-椭圆曲线密码学详解
# Day 191: 椭圆曲线密码学详解 > 密码学系列第 11 天 | 预计阅读时间:45 分钟 | 难度:★★★★★ --- ## 清单 目录 1. [椭圆曲线概述](#椭圆曲线概述) 2. [椭圆曲线数学基础](#椭圆曲线数学基础) 3. [椭圆曲线离散对数问题](#椭圆曲线离散对数问题) 4. [常用椭圆曲线](#常用椭圆曲线) 5. [ECC 密钥生成](#ecc 密钥生成) 6. [ECDH 密钥交换](#ecdh 密钥交换) 7. [ECDSA 数字签名](#ecdsa 数字签名) 8. [EdDSA 签名算法](#eddsa 签名算法) 9. [ECC vs RSA](#ecc-vs-rsa) 10. [实战应用](#实战应用) 11. [安全实践](#安全实践) 12. [总结与思考](#总结与思考) 13. [参考资料](#参考资料) --- ## 椭圆曲线概述 ### 什么是椭圆曲线密码学 **椭圆曲线密码学(ECC)定义**: ``` ┌─────────────────────────────────────────────────────────────┐ │ 椭圆曲线密码学(ECC) │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 定义: │ │ 基于椭圆曲线离散对数问题(ECDLP)的公钥密码体制 │ │ │ │ 提出时间: │ │ ├── 1985 年:Neal Koblitz │ │ └── 1985 年:Victor Miller(独立提出) │ │ │ │ 核心优势: │ │ ├── 密钥短:256 位 ECC ≈ 3072 位 RSA │ │ ├── 计算快:签名和密钥交换速度更快 │ │ ├── 带宽低:传输数据量小 │ │ └── 资源少:适合移动设备和 IoT │ │ │ │ 应用领域: │ │ ├── TLS/SSL:HTTPS 加密 │ │ ├── 比特币:ECDSA 签名 │ │ ├── SSH:密钥交换和认证 │ │ ├── 智能卡:资源受限环境 │ │ └── 移动通信:5G 安全 │ │ │ │ 常见算法: │ │ ├── ECDH:椭圆曲线 Diffie-Hellman 密钥交换 │ │ ├── ECDSA:椭圆曲线数字签名算法 │ │ ├── EdDSA:Edwards 曲线数字签名算法 │ │ └── ECIES:椭圆曲线集成加密方案 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### ECC 发展历史 **ECC 发展历程**: ``` ┌─────────────────────────────────────────────────────────────┐ │ ECC 发展历史 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 1985 年:理论提出 │ │ ├── Koblitz 和 Miller 独立提出 ECC 概念 │ │ └── 基于椭圆曲线离散对数问题 │ │ │ │ 1992 年:首个实现 │ │ └── Scott Vanstone 等人实现第一个 ECC 系统 │ │ │ │ 2000 年:标准化开始 │ │ ├── ANSI X9.62:ECDSA 标准 │ │ ├── ANSI X9.63:ECDH 标准 │ │ └── IEEE P1363:公钥密码标准 │ │ │ │ 2005 年:NIST 推荐 │ │ └── NIST SP 800-56A:推荐 ECC 用于密钥协商 │ │ │ │ 2009 年:比特币采用 │ │ └── 比特币使用 secp256k1 曲线和 ECDSA 签名 │ │ │ │ 2013 年:EdDSA 提出 │ │ └── Daniel Bernstein 等人提出 Ed25519 │ │ │ │ 2017 年:Cloudflare 部署 │ │ └── Cloudflare 默认使用 ECC 证书 │ │ │ │ 2020 年:TLS 1.3 │ │ └── TLS 1.3 强制支持 ECDHE 密钥交换 │ │ │ │ 现状: │ │ ├── 主流浏览器:默认支持 ECC │ │ ├── 证书机构:大量签发 ECC 证书 │ │ └── 移动设备:硬件加速支持 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 椭圆曲线数学基础 ### 椭圆曲线方程 **Weierstrass 方程**: ``` ┌─────────────────────────────────────────────────────────────┐ │ 椭圆曲线方程 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 标准 Weierstrass 方程(特征≠2,3): │ │ y² = x³ + ax + b │ │ │ │ 参数要求: │ │ ├── 4a³ + 27b² ≠ 0(非奇异条件) │ │ └── a, b ∈ 有限域 Fp │ │ │ │ 示例曲线: │ │ ├── y² = x³ + 7(比特币 secp256k1) │ │ │ └── a = 0, b = 7 │ │ │ │ │ └── y² = x³ - 3x + b(NIST P-256) │ │ └── a = -3, b 特定值 │ │ │ │ 曲线上的点: │ │ ├── 满足方程的 (x, y) 坐标对 │ │ └── 无穷远点 O(单位元) │ │ │ │ 有限域上的椭圆曲线: │ │ ├── 定义在 Fp 上(p 为大素数) │ │ ├── 点的数量有限 │ │ └── 形成有限阿贝尔群 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### 群运算 **椭圆曲线群运算**: ``` ┌─────────────────────────────────────────────────────────────┐ │ 椭圆曲线群运算 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 点加法(P + Q): │ │ ├── 几何解释: │ │ │ 1. 过 P 和 Q 作直线,交曲线于 R │ │ │ 2. R 关于 x 轴对称得到 P + Q │ │ │ │ │ ├── 代数公式(P ≠ Q): │ │ │ λ = (yQ - yP) / (xQ - xP) mod p │ │ │ xR = λ² - xP - xQ mod p │ │ │ yR = λ(xP - xR) - yP mod p │ │ │ │ │ └── 代数公式(P = Q,点倍): │ │ λ = (3xP² + a) / (2yP) mod p │ │ xR = λ² - 2xP mod p │ │ yR = λ(xP - xR) - yP mod p │ │ │ │ 群性质: │ │ ├── 封闭性:P + Q 仍在曲线上 │ │ ├── 结合律:(P + Q) + R = P + (Q + R) │ │ ├── 单位元:P + O = P(O 为无穷远点) │ │ ├── 逆元:P + (-P) = O(-P 为 P 关于 x 轴对称点) │ │ └── 交换律:P + Q = Q + P │ │ │ │ 标量乘法(k × P): │ │ ├── 定义:P + P + ... + P(k 次) │ │ ├── 计算:双倍 - 加算法(Double-and-Add) │ │ └── 应用:公钥 = 私钥 × 基点 │ │ │ │ 双倍 - 加算法示例: │ │ 计算 13 × P: │ │ 13 = 1101₂ │ │ ├── 1: Q = P │ │ ├── 1: Q = 2Q = 2P, Q = Q + P = 3P │ │ ├── 0: Q = 2Q = 6P │ │ └── 1: Q = 2Q = 12P, Q = Q + P = 13P │ │ 共 3 次加倍,2 次加法 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### 离散对数问题 **椭圆曲线离散对数问题(ECDLP)**: ``` ┌─────────────────────────────────────────────────────────────┐ │ 椭圆曲线离散对数问题(ECDLP) │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 问题描述: │ │ 给定: │ │ ├── 椭圆曲线 E 定义在 Fp 上 │ │ ├── 基点 G(阶为 n) │ │ ├── 点 P = k × G(k 为整数) │ │ │ │ │ 求解: │ │ └── 整数 k(0 ≤ k < n) │ │ │ │ 困难性: │ │ ├── 已知 k 和 G,计算 P = k × G:容易(O(log k)) │ │ └── 已知 P 和 G,求解 k:困难(O(√n)) │ │ │ │ 最佳已知算法: │ │ ├── Pollard's Rho:O(√n) 群运算 │ │ ├── Baby-step Giant-step:O(√n) 时间,O(√n) 空间 │ │ └── 指数积分法:不适用于椭圆曲线 │ │ │ │ 安全参数对比: │ │ │ ECC 密钥大小 │ 安全强度 │ RSA 等效大小 │ │ │ │--------------│----------│--------------│ │ │ │ 160 位 │ 80 位 │ 1024 位 │ │ │ │ 256 位 │ 128 位 │ 3072 位 │ │ │ │ 384 位 │ 192 位 │ 7680 位 │ │ │ │ 521 位 │ 256 位 │ 15360 位 │ │ │ │ │ 结论: │ │ "ECC 以短得多的密钥提供相同的安全性, │ │ 这是 ECC 最大的优势。" │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 常用椭圆曲线 ### NIST 推荐曲线 **NIST 推荐曲线(Fp 素数域)**: ``` ┌─────────────────────────────────────────────────────────────┐ │ NIST 推荐曲线 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ P-192(secp192r1): │ │ ├── 密钥大小:192 位 │ │ ├── 安全强度:80 位 │ │ ├── 状态:已不推荐(强度不足) │ │ └── 用途:遗留系统 │ │ │ │ P-256(secp256r1): │ │ ├── 密钥大小:256 位 │ │ ├── 安全强度:128 位 │ │ ├── 状态:广泛使用,推荐 │ │ ├── 应用:TLS、JWT、Android 密钥库 │ │ └── 参数: │ │ p = 2²⁵⁶ - 2²²⁴ + 2¹⁹² + 2⁹⁶ - 1 │ │ a = -3 │ │ b = 特定常数 │ │ │ │ P-384(secp384r1): │ │ ├── 密钥大小:384 位 │ │ ├── 安全强度:192 位 │ │ ├── 状态:推荐用于高安全场景 │ │ └── 应用:TLS、政府系统 │ │ │ │ P-521(secp521r1): │ │ ├── 密钥大小:521 位 │ │ ├── 安全强度:256 位 │ │ ├── 状态:推荐用于极高安全场景 │ │ └── 应用:根证书、长期密钥 │ │ │ │ 争议: │ │ ! NIST 曲线参数来源不透明(可能包含后门) │ │ ! Dual_EC_DRBG 事件影响信任 │ │ ✓ 建议使用 Curve25519 等透明参数曲线 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### Curve25519 **Curve25519(现代推荐)**: ``` ┌─────────────────────────────────────────────────────────────┐ │ Curve25519 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 设计者:Daniel J. Bernstein(2006 年) │ │ │ │ 曲线类型:Montgomery 曲线 │ │ 方程:y² = x³ + 486662x² + x(mod 2²⁵⁵-19) │ │ │ │ 特点: │ │ ├── 参数透明:"nothing up my sleeve"数字 │ │ ├── 速度快:专为快速实现设计 │ │ ├── 安全:抵抗侧信道攻击 │ │ ├── 简单:易于正确实现 │ │ └── 无专利:自由使用 │ │ │ │ 应用: │ │ ├── X25519:ECDH 密钥交换 │ │ ├── Ed25519:数字签名 │ │ ├── SSH:默认密钥交换算法 │ │ ├── TLS 1.3:支持的曲线之一 │ │ ├── Signal 协议:即时通讯加密 │ │ └── WireGuard:VPN 协议 │ │ │ │ 性能: │ │ ├── 密钥交换:<1ms(现代 CPU) │ │ ├── 签名:<1ms │ │ └── 验证:<3ms │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### secp256k1 **secp256k1(比特币曲线)**: ``` ┌─────────────────────────────────────────────────────────────┐ │ secp256k1 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 曲线方程:y² = x³ + 7(mod p) │ │ │ │ 参数: │ │ ├── p = 2²⁵⁶ - 2³² - 977(特殊形式素数) │ │ ├── a = 0 │ │ ├── b = 7 │ │ └── 基点 G:特定坐标 │ │ │ │ 特点: │ │ ├── Koblitz 曲线:特殊形式,计算更快 │ │ ├── 参数简单:a=0, b=7 │ │ └── 无已知弱点:安全使用多年 │ │ │ │ 应用: │ │ ├── 比特币:地址和交易签名 │ │ ├── 以太坊:账户和交易签名 │ │ └── 其他加密货币:广泛采用 │ │ │ │ 密钥格式: │ │ ├── 私钥:32 字节(256 位)随机数 │ │ ├── 公钥:64 字节(未压缩)或 33 字节(压缩) │ │ └── 地址:RIPEMD160(SHA256(公钥)) │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## ECC 密钥生成 ### 密钥生成流程 **ECC 密钥对生成**: ``` ┌─────────────────────────────────────────────────────────────┐ │ ECC 密钥对生成 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 输入: │ │ ├── 椭圆曲线参数(p, a, b, G, n, h) │ │ └── 安全随机数生成器 │ │ │ │ 步骤: │ │ 1. 选择私钥 d: │ │ ├── 随机选择整数 d │ │ └── 1 ≤ d ≤ n-1(n 为曲线阶) │ │ │ │ 2. 计算公钥 Q: │ │ ├── Q = d × G │ │ └── G 为基点,× 为标量乘法 │ │ │ │ 3. 输出: │ │ ├── 私钥:d(保密) │ │ └── 公钥:Q = (x, y)(公开) │ │ │ │ 安全要求: │ │ ├── 私钥必须均匀随机选择 │ │ ├── 私钥不能为 0 或 n │ │ ├── 使用 CSPRNG 生成私钥 │ │ └── 私钥长度应匹配曲线安全强度 │ │ │ │ 示例(P-256): │ │ ├── 私钥:32 字节随机数 │ │ ├── 公钥:64 字节(x, y 各 32 字节) │ │ └── 安全强度:128 位 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### 代码实现 **Python ECC 密钥生成**: ```python from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.backends import default_backend import secrets # ============= 生成 ECC 密钥对 ============= def generate_ecc_keypair(curve='secp256r1'): """生成 ECC 密钥对""" # 选择曲线 curves = { 'secp256r1': ec.SECP256R1(), 'secp384r1': ec.SECP384R1(), 'secp521r1': ec.SECP521R1(), 'secp256k1': ec.SECP256K1(), } if curve not in curves: raise ValueError(f"不支持的曲线:{curve}") # 生成密钥对 private_key = ec.generate_private_key( curves[curve], backend=default_backend() ) # 获取公钥 public_key = private_key.public_key() return private_key, public_key # ============= 密钥序列化 ============= def serialize_keys(private_key, public_key): """序列化密钥""" from cryptography.hazmat.primitives import serialization # 私钥 PEM 格式 private_pem = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ) # 公钥 PEM 格式 public_pem = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) # 私钥 DER 格式(二进制) private_der = private_key.private_bytes( encoding=serialization.Encoding.DER, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ) # 公钥 DER 格式(二进制) public_der = public_key.public_bytes( encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo ) return { 'private_pem': private_pem, 'public_pem': public_pem, 'private_der': private_der, 'public_der': public_der, } # ============= 密钥加载 ============= def load_private_key(pem_data): """加载私钥""" from cryptography.hazmat.primitives import serialization private_key = serialization.load_pem_private_key( pem_data, password=None, backend=default_backend() ) return private_key def load_public_key(pem_data): """加载公钥""" from cryptography.hazmat.primitives import serialization public_key = serialization.load_pem_public_key( pem_data, backend=default_backend() ) return public_key if __name__ == "__main__": # 生成密钥对 private_key, public_key = generate_ecc_keypair('secp256r1') print("=== ECC 密钥对生成 ===") print(f"曲线:secp256r1 (P-256)") print(f"私钥大小:{private_key.key_size} 位") print(f"公钥大小:{public_key.key_size} 位") # 序列化 keys = serialize_keys(private_key, public_key) print(f"\n私钥 PEM(前 100 字符):{keys['private_pem'][:100]}...") print(f"公钥 PEM(前 100 字符):{keys['public_pem'][:100]}...") ``` --- ## ECDH 密钥交换 ### ECDH 原理 **椭圆曲线 Diffie-Hellman(ECDH)**: ``` ┌─────────────────────────────────────────────────────────────┐ │ ECDH 密钥交换 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 参与方:Alice 和 Bob │ │ │ │ 公共参数: │ │ ├── 椭圆曲线 E(如 P-256) │ │ └── 基点 G │ │ │ │ 密钥交换流程: │ │ │ │ Alice Bob │ │ ───── ─── │ │ 1. 生成私钥 a │ │ │ 计算公钥 A = a × G │ │ │ 2. 发送 A ─────────────────────> │ │ │ 3. │ <───────────────────── 生成私钥 b │ │ │ 计算公钥 B = b × G │ │ 4. │ <───────────────────── 发送 B │ │ 5. 计算共享密钥: │ 计算共享密钥: │ │ S = a × B = a × b × G │ S = b × A = b × a × G │ │ │ │ 结果: │ │ ├── Alice 和 Bob 得到相同的 S │ │ ├── S 的 x 坐标作为共享密钥 │ │ └── 窃听者无法从 A 和 B 计算 S(ECDLP 困难) │ │ │ │ 临时 ECDH(ECDHE): │ │ ├── 每次会话生成新密钥对 │ │ ├── 提供前向安全性 │ │ └── TLS 1.3 强制使用 ECDHE │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### ECDH 代码实现 **Python ECDH 密钥交换**: ```python from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.kdf.hkdf import HKDF # ============= Alice 生成密钥对 ============= def alice_generate(): """Alice 生成密钥对""" private_key = ec.generate_private_key( ec.SECP256R1(), backend=default_backend() ) public_key = private_key.public_key() # 序列化公钥(发送给 Bob) public_pem = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) return private_key, public_pem # ============= Bob 生成密钥对并计算共享密钥 ============= def bob_generate_and_derive(alice_public_pem): """Bob 生成密钥对并计算共享密钥""" # Bob 生成密钥对 bob_private = ec.generate_private_key( ec.SECP256R1(), backend=default_backend() ) # 加载 Alice 的公钥 alice_public = serialization.load_pem_public_key( alice_public_pem, backend=default_backend() ) # 计算共享密钥(ECDH) shared_key = bob_private.exchange(ec.ECDH(), alice_public) # 使用 HKDF 派生最终密钥 derived_key = HKDF( algorithm=hashes.SHA256(), length=32, salt=None, info=b"ecdhes", backend=default_backend() ).derive(shared_key) return bob_private, derived_key # ============= Alice 计算共享密钥 ============= def alice_derive(alice_private, bob_public_pem): """Alice 计算共享密钥""" # 加载 Bob 的公钥 bob_public = serialization.load_pem_public_key( bob_public_pem, backend=default_backend() ) # 计算共享密钥(ECDH) shared_key = alice_private.exchange(ec.ECDH(), bob_public) # 使用 HKDF 派生最终密钥 derived_key = HKDF( algorithm=hashes.SHA256(), length=32, salt=None, info=b"ecdhes", backend=default_backend() ).derive(shared_key) return derived_key if __name__ == "__main__": print("=== ECDH 密钥交换演示 ===\n") # Alice 生成密钥对 alice_private, alice_public_pem = alice_generate() print(f"Alice 公钥(前 50 字符):{alice_public_pem[:50].decode()}...") # Bob 生成密钥对并计算共享密钥 bob_private, bob_shared_key = bob_generate_and_derive(alice_public_pem) print(f"Bob 计算的共享密钥:{bob_shared_key.hex()}") # Bob 发送公钥给 Alice(模拟) bob_public_pem = bob_private.public_key().public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) print(f"Bob 公钥(前 50 字符):{bob_public_pem[:50].decode()}...") # Alice 计算共享密钥 alice_shared_key = alice_derive(alice_private, bob_public_pem) print(f"Alice 计算的共享密钥:{alice_shared_key.hex()}") # 验证 print(f"\n✓ 密钥匹配:{alice_shared_key == bob_shared_key}") ``` --- ## ECDSA 数字签名 ### ECDSA 原理 **椭圆曲线数字签名算法(ECDSA)**: ``` ┌─────────────────────────────────────────────────────────────┐ │ ECDSA 数字签名 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 签名生成(私钥持有者): │ │ ├── 输入:消息 m,私钥 d │ │ ├── 步骤: │ │ │ 1. 计算消息哈希:h = H(m) │ │ │ 2. 随机选择 k:1 ≤ k < n │ │ │ 3. 计算点 (x, y) = k × G │ │ │ 4. 计算 r = x mod n │ │ │ 5. 计算 s = k⁻¹(h + d × r) mod n │ │ │ 6. 如果 r=0 或 s=0,重新选择 k │ │ │ │ │ └── 输出:签名 (r, s) │ │ │ │ 签名验证(公钥持有者): │ │ ├── 输入:消息 m,签名 (r, s),公钥 Q │ │ ├── 步骤: │ │ │ 1. 验证 r, s 范围:1 ≤ r, s < n │ │ │ 2. 计算消息哈希:h = H(m) │ │ │ 3. 计算 w = s⁻¹ mod n │ │ │ 4. 计算 u1 = h × w mod n │ │ │ 5. 计算 u2 = r × w mod n │ │ │ 6. 计算点 (x, y) = u1 × G + u2 × Q │ │ │ 7. 验证 r ≡ x (mod n) │ │ │ │ │ └── 输出:有效/无效 │ │ │ │ 关键安全要求: │ │ ├── k 必须每次签名随机生成 │ │ ├── k 必须保密(泄露 k = 泄露私钥) │ │ └── k 不能重复使用(重复使用 = 泄露私钥) │ │ │ │ 历史教训: │ │ ├── 2010 年:Android Bitcoin 钱包 │ │ │ └── k 重复使用,私钥泄露,损失比特币 │ │ │ │ │ └── 2011 年:Sony PS3 签名 │ │ └── k 固定不变,私钥被破解 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### ECDSA 代码实现 **Python ECDSA 签名**: ```python from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.backends import default_backend # ============= 生成密钥对 ============= def generate_keypair(): """生成 ECDSA 密钥对""" private_key = ec.generate_private_key( ec.SECP256R1(), backend=default_backend() ) public_key = private_key.public_key() return private_key, public_key # ============= 签名 ============= def sign_message(private_key, message): """使用 ECDSA 签名消息""" from cryptography.hazmat.primitives.asymmetric.utils import encode_dss_signature # 确保消息是字节 if isinstance(message, str): message = message.encode('utf-8') # 签名 signature = private_key.sign( message, ec.ECDSA(hashes.SHA256()) ) return signature # ============= 验证 ============= def verify_signature(public_key, message, signature): """验证 ECDSA 签名""" try: # 确保消息是字节 if isinstance(message, str): message = message.encode('utf-8') # 验证 public_key.verify( signature, message, ec.ECDSA(hashes.SHA256()) ) return True except Exception as e: print(f"验证失败:{e}") return False # ============= 签名格式转换 ============= def signature_to_der(signature): """将签名转换为 DER 格式""" # cryptography 库默认返回 DER 格式 return signature def signature_to_pem(signature): """将签名转换为 PEM 格式""" import base64 der = signature_to_der(signature) b64 = base64.b64encode(der).decode() pem = "-----BEGIN SIGNATURE-----\n" for i in range(0, len(b64), 64): pem += b64[i:i+64] + "\n" pem += "-----END SIGNATURE-----\n" return pem if __name__ == "__main__": print("=== ECDSA 签名演示 ===\n") # 生成密钥对 private_key, public_key = generate_keypair() print(f"曲线:secp256r1 (P-256)") print(f"密钥大小:{private_key.key_size} 位\n") # 消息 message = "Hello, ECC World!" print(f"原始消息:{message}") # 签名 signature = sign_message(private_key, message) print(f"签名长度:{len(signature)} 字节") print(f"签名(hex):{signature[:32].hex()}...") # 验证(正确消息) is_valid = verify_signature(public_key, message, signature) print(f"\n✓ 验证结果(正确消息):{'有效' if is_valid else '无效'}") # 验证(篡改消息) tampered_message = "Hello, ECC World!" # 故意修改 is_valid = verify_signature(public_key, tampered_message, signature) print(f"✓ 验证结果(篡改消息):{'有效' if is_valid else '无效'}") ``` --- ## EdDSA 签名算法 ### EdDSA 原理 **Edwards 曲线数字签名算法(EdDSA)**: ``` ┌─────────────────────────────────────────────────────────────┐ │ EdDSA 签名算法 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 设计者:Daniel J. Bernstein 等人(2011 年) │ │ │ │ 曲线:Edwards 曲线(如 Ed25519) │ │ 方程:x² + y² = 1 + d·x²·y²(mod p) │ │ │ │ 特点: │ │ ├── 确定性:不需要随机数 k(避免 ECDSA 的 k 问题) │ │ ├── 快速:专为速度优化 │ │ ├── 安全:抵抗侧信道攻击 │ │ ├── 简单:易于正确实现 │ │ └── 紧凑:签名固定 64 字节 │ │ │ │ Ed25519 参数: │ │ ├── 曲线:Curve25519 的 Edwards 形式 │ │ ├── 密钥大小:32 字节(256 位) │ │ ├── 签名大小:64 字节 │ │ ├── 安全强度:128 位 │ │ └── 性能:<1ms 签名,<3ms 验证 │ │ │ │ 签名流程(简化): │ │ ├── 1. 哈希私钥得到前缀和后缀 │ │ ├── 2. 计算 r = H(前缀 || 消息) │ │ ├── 3. 计算 R = r × G │ │ ├── 4. 计算 k = H(R || 公钥 || 消息) │ │ └── 5. 计算 s = (r + k × 私钥) mod n │ │ 签名 = (R, s) │ │ │ │ 应用: │ │ ├── SSH:Ed25519 密钥 │ │ ├── GPG:Ed25519 签名 │ │ ├── TLS 1.3:Ed25519 证书 │ │ ├── Signal:消息签名 │ │ └── 区块链:多种加密货币采用 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### EdDSA 代码实现 **Python EdDSA 签名**: ```python from cryptography.hazmat.primitives.asymmetric.ed25519 import ( Ed25519PrivateKey, Ed25519PublicKey ) from cryptography.hazmat.primitives import serialization # ============= 生成密钥对 ============= def generate_ed25519_keypair(): """生成 Ed25519 密钥对""" private_key = Ed25519PrivateKey.generate() public_key = private_key.public_key() return private_key, public_key # ============= 签名 ============= def sign_ed25519(private_key, message): """使用 Ed25519 签名消息""" if isinstance(message, str): message = message.encode('utf-8') signature = private_key.sign(message) return signature # ============= 验证 ============= def verify_ed25519(public_key, message, signature): """验证 Ed25519 签名""" try: if isinstance(message, str): message = message.encode('utf-8') public_key.verify(signature, message) return True except Exception as e: print(f"验证失败:{e}") return False # ============= 密钥序列化 ============= def serialize_ed25519(private_key, public_key): """序列化 Ed25519 密钥""" # 私钥 PEM private_pem = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() ) # 公钥 PEM public_pem = public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo ) # 私钥原始字节(32 字节) private_bytes = private_key.private_bytes( encoding=serialization.Encoding.Raw, format=serialization.PrivateFormat.Raw, encryption_algorithm=serialization.NoEncryption() ) # 公钥原始字节(32 字节) public_bytes = public_key.public_bytes( encoding=serialization.Encoding.Raw, format=serialization.PublicFormat.Raw, encryption_algorithm=serialization.NoEncryption() ) return { 'private_pem': private_pem, 'public_pem': public_pem, 'private_raw': private_bytes, 'public_raw': public_bytes, } if __name__ == "__main__": print("=== Ed25519 签名演示 ===\n") # 生成密钥对 private_key, public_key = generate_ed25519_keypair() print(f"算法:Ed25519") print(f"密钥大小:256 位") print(f"签名大小:64 字节(固定)\n") # 消息 message = "Hello, Ed25519!" print(f"原始消息:{message}") # 签名 signature = sign_ed25519(private_key, message) print(f"签名长度:{len(signature)} 字节") print(f"签名(hex):{signature[:32].hex()}...") # 验证(正确消息) is_valid = verify_ed25519(public_key, message, signature) print(f"\n✓ 验证结果(正确消息):{'有效' if is_valid else '无效'}") # 验证(篡改消息) tampered_message = "Hello, Ed25519!" # 故意修改 is_valid = verify_ed25519(public_key, tampered_message, signature) print(f"✓ 验证结果(篡改消息):{'有效' if is_valid else '无效'}") # 序列化 keys = serialize_ed25519(private_key, public_key) print(f"\n私钥原始字节:{keys['private_raw'].hex()}") print(f"公钥原始字节:{keys['public_raw'].hex()}") ``` --- ## ECC vs RSA ### 性能对比 **ECC 与 RSA 对比**: ``` ┌─────────────────────────────────────────────────────────────┐ │ ECC vs RSA 对比 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 安全强度对比: │ │ ┌──────────────┬────────────┬─────────────┐ │ │ │ ECC 密钥大小 │ 安全强度 │ RSA 等效大小 │ │ │ ├──────────────┼────────────┼─────────────┤ │ │ │ 160 位 │ 80 位 │ 1024 位 │ │ │ │ 224 位 │ 112 位 │ 2048 位 │ │ │ │ 256 位 │ 128 位 │ 3072 位 │ │ │ │ 384 位 │ 192 位 │ 7680 位 │ │ │ │ 521 位 │ 256 位 │ 15360 位 │ │ │ └──────────────┴────────────┴─────────────┘ │ │ │ │ 性能对比(相对速度,RSA-2048=1): │ │ ┌────────────────┬─────────────┬──────────────┐ │ │ │ 操作 │ RSA-2048 │ ECC P-256 │ │ │ ├────────────────┼─────────────┼──────────────┤ │ │ │ 密钥生成 │ 1x │ 5x │ │ │ │ 签名 │ 1x │ 20x │ │ │ │ 验证 │ 1x │ 0.5x │ │ │ │ 密钥交换 │ 1x │ 10x │ │ │ │ 密钥大小 │ 2048 位 │ 256 位 │ │ │ │ 签名大小 │ 2048 位 │ 512 位 │ │ │ └────────────────┴─────────────┴──────────────┘ │ │ │ │ 资源消耗对比: │ │ ├── CPU:ECC 计算量更小 │ │ ├── 内存:ECC 占用更少 │ │ ├── 带宽:ECC 传输数据更少 │ │ └── 存储:ECC 密钥和签名更小 │ │ │ │ 适用场景: │ │ ├── ECC 优势场景: │ │ │ - 移动设备(电池有限) │ │ │ - IoT 设备(计算能力弱) │ │ │ - 高并发服务器(性能要求高) │ │ │ - 低带宽网络(卫星、移动网络) │ │ │ - 实时通信(延迟敏感) │ │ │ │ │ └── RSA 优势场景: │ │ - 遗留系统兼容 │ │ - 需要加密(ECC 加密方案复杂) │ │ - 硬件已优化(HSM 支持 RSA) │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### 选择建议 **算法选择建议**: ``` ┌─────────────────────────────────────────────────────────────┐ │ 算法选择建议 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 推荐选择 ECC 的场景: │ │ ✓ 新项目默认选择 │ │ ✓ 移动应用 │ │ ✓ IoT 设备 │ │ ✓ TLS/SSL 证书 │ │ ✓ 密钥交换(ECDHE) │ │ ✓ 数字签名(ECDSA/EdDSA) │ │ ✓ 区块链/加密货币 │ │ ✓ 即时通讯(Signal 协议) │ │ │ │ 仍使用 RSA 的场景: │ │ ! 遗留系统兼容 │ │ ! 需要加密功能(ECIES 复杂) │ │ ! 特定硬件要求(HSM 只支持 RSA) │ │ ! 法规要求(某些行业指定 RSA) │ │ │ │ 曲线选择: │ │ ├── 通用场景:P-256(secp256r1) │ │ ├── 高安全场景:P-384(secp384r1) │ │ ├── 现代推荐:Curve25519 / Ed25519 │ │ ├── 区块链:secp256k1 │ │ └── 避免使用:P-192(强度不足) │ │ │ │ 迁移建议: │ │ ├── 评估现有系统 RSA 密钥大小 │ │ ├── RSA-1024:立即迁移至 ECC │ │ ├── RSA-2048:计划迁移至 ECC │ │ └── RSA-4096:可继续使用,考虑迁移至 ECC │ │ │ └─────────────────────────────────────────────────────────────┘ ``` --- ## 实战应用 ### TLS 中的 ECC **TLS 1.3 中的 ECC**: ```python # TLS 1.3 强制使用 ECDHE 密钥交换 # 以下为 OpenSSL 配置示例 from cryptography import x509 from cryptography.x509.oid import NameOID from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.backends import default_backend from datetime import datetime, timedelta # ============= 生成 ECC 证书 ============= def generate_ecc_certificate(): """生成 ECC 证书""" # 生成 ECC 密钥对 private_key = ec.generate_private_key( ec.SECP256R1(), backend=default_backend() ) # 证书主题 subject = issuer = x509.Name([ x509.NameAttribute(NameOID.COUNTRY_NAME, "CN"), x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Beijing"), x509.NameAttribute(NameOID.LOCALITY_NAME, "Beijing"), x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Example Corp"), x509.NameAttribute(NameOID.COMMON_NAME, "example.com"), ]) # 创建证书 cert = x509.CertificateBuilder().subject_name( subject ).issuer_name( issuer ).public_key( private_key.public_key() ).serial_number( x509.random_serial_number() ).not_valid_before( datetime.utcnow() ).not_valid_after( datetime.utcnow() + timedelta(days=365) ).add_extension( x509.SubjectAlternativeName([ x509.DNSName("example.com"), x509.DNSName("www.example.com"), ]), critical=False, ).sign(private_key, hashes.SHA256(), default_backend()) return private_key, cert if __name__ == "__main__": print("=== 生成 ECC 证书 ===") private_key, cert = generate_ecc_certificate() print(f"曲线:secp256r1") print(f"证书主题:{cert.subject}") print(f"有效期:{cert.not_valid_before} 至 {cert.not_valid_after}") print(f"签名算法:{cert.signature_algorithm_oid._name}") ``` ### SSH 中的 Ed25519 **SSH Ed25519 密钥**: ```bash # ============= 生成 Ed25519 SSH 密钥 ============= # 命令: ssh-keygen -t ed25519 -C "your_email@example.com" # 输出: # Generating public/private ed25519 key pair. # Enter file in which to save the key (/home/user/.ssh/id_ed25519): # Enter passphrase (empty for no passphrase): # Enter same passphrase again: # Your identification has been saved in /home/user/.ssh/id_ed25519 # Your public key has been saved in /home/user/.ssh/id_ed25519.pub # ============= 查看密钥 ============= # 私钥: cat ~/.ssh/id_ed25519 # -----BEGIN OPENSSH PRIVATE KEY----- # b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW # QyNTUxOQAAACB... # 公钥: cat ~/.ssh/id_ed25519.pub # ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... your_email@example.com # ============= 添加到 SSH 代理 ============= ssh-add ~/.ssh/id_ed25519 # ============= 复制到服务器 ============= ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server # ============= SSH 配置(强制使用 Ed25519) ============= # /etc/ssh/sshd_config: # PubkeyAcceptedKeyTypes ssh-ed25519 # HostKeyAlgorithms ssh-ed25519 ``` --- ## 安全实践 ### 最佳实践 ``` ┌─────────────────────────────────────────────────────────────┐ │ ECC 安全实践 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 应该做的: │ │ ✓ 使用现代曲线(Curve25519、Ed25519、P-256) │ │ ✓ 使用临时密钥(ECDHE)提供前向安全性 │ │ ✓ 使用 EdDSA 代替 ECDSA(确定性签名) │ │ ✓ 验证公钥(防止中间人攻击) │ │ ✓ 使用 HKDF 派生密钥 │ │ ✓ 定期轮换密钥 │ │ ✓ 安全存储私钥(HSM、密钥库) │ │ │ │ 不应该做的: │ │ ✗ 使用弱曲线(P-192、secp160r1) │ │ ✗ 使用静态 ECDH(无前向安全性) │ │ ✗ 重复使用随机数 k(ECDSA) │ │ ✗ 自己实现椭圆曲线运算(使用成熟库) │ │ ✗ 使用有争议的曲线(Dual_EC_DRBG 相关) │ │ ✗ 明文传输私钥 │ │ │ │ 库选择: │ │ ├── Python:cryptography、PyNaCl │ │ ├── Java:Bouncy Castle、Tink │ │ ├── C/C++:libsodium、OpenSSL │ │ ├── Go:crypto/elliptic、ed25519 │ │ └── Node.js:crypto 模块、tweetnacl │ │ │ │ 实现注意事项: │ │ ├── 使用常数时间比较(防止时序攻击) │ │ ├── 清除敏感数据(私钥、随机数) │ │ ├── 验证输入(点是否在曲线上) │ │ └── 使用经过审计的库 │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### 常见错误 **ECC 使用错误**: ```python # ============= 错误 1:使用弱曲线 ============= # ✗ 错误: from cryptography.hazmat.primitives.asymmetric import ec private_key = ec.generate_private_key(ec.SECT163R2(), backend) # 163 位,弱! # ✓ 正确: private_key = ec.generate_private_key(ec.SECP256R1(), backend) # 256 位 # ============= 错误 2:ECDSA 重复使用 k ============= # ✗ 错误:手动实现 ECDSA 且 k 不随机 # 后果:私钥可被计算出来 # ✓ 正确:使用库函数,自动处理 k signature = private_key.sign(message, ec.ECDSA(hashes.SHA256())) # ============= 错误 3:不验证公钥 ============= # ✗ 错误:直接使用对方公钥 shared_key = private_key.exchange(ec.ECDH(), unverified_public_key) # ✓ 正确:验证公钥在曲线上 from cryptography.hazmat.primitives.asymmetric.ec import ( derive_private_key, EllipticCurvePublicNumbers ) # 库会自动验证,但应用层也应验证身份 # ============= 错误 4:静态 ECDH ============= # ✗ 错误:长期使用同一密钥对 static_private = load_static_private_key() shared_key = static_private.exchange(ec.ECDH(), peer_public) # ✓ 正确:每次会话生成新密钥对(ECDHE) ephemeral_private = ec.generate_private_key(ec.SECP256R1()) shared_key = ephemeral_private.exchange(ec.ECDH(), peer_public) # 会话结束后删除 ephemeral_private # ============= 错误 5:自己实现曲线运算 ============= # ✗ 错误:自己写点加法、标量乘法 # 风险:侧信道攻击、实现错误 # ✓ 正确:使用成熟库 from cryptography.hazmat.primitives.asymmetric import ec # 库经过严格测试和审计 ``` --- ## 总结与思考 ### 核心要点回顾 **ECC 知识框架**: ``` ┌─────────────────────────────────────────────────────────────┐ │ ECC 知识框架 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 数学基础: │ │ ├── 椭圆曲线方程:y² = x³ + ax + b │ │ ├── 群运算:点加法、标量乘法 │ │ └── ECDLP:离散对数问题(安全基础) │ │ │ │ 常用曲线: │ │ ├── NIST 曲线:P-256、P-384、P-521 │ │ ├── Curve25519:现代推荐 │ │ └── secp256k1:比特币曲线 │ │ │ │ 核心算法: │ │ ├── ECDH:密钥交换 │ │ ├── ECDSA:数字签名 │ │ └── EdDSA:改进签名(确定性) │ │ │ │ 优势对比: │ │ ├── 密钥短:256 位 ECC ≈ 3072 位 RSA │ │ ├── 计算快:签名和密钥交换更快 │ │ └── 资源少:适合移动和 IoT │ │ │ │ 安全实践: │ │ ├── 使用现代曲线(Curve25519、Ed25519) │ │ ├── 使用 ECDHE(前向安全性) │ │ └── 使用成熟库(不自己实现) │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### 深入思考 **1. 为什么 ECC 没有被更早采用?** - 专利问题:早期 ECC 专利限制了应用 - 实现复杂:比 RSA 更难正确实现 - 信任问题:NIST 曲线参数来源不透明 - 现状:专利过期,Curve25519 等透明曲线出现 **2. ECC 会被量子计算破解吗?** - 会:Shor 算法可以在量子计算机上破解 ECC - 时间:需要数千量子比特,目前技术达不到 - 应对:后量子密码学(PQC)正在标准化 - NIST PQC:CRYSTALS-Kyber(密钥交换)、CRYSTALS-Dilithium(签名) **3. 应该选择哪条曲线?** - 通用场景:P-256(广泛支持) - 新项目:Curve25519 / Ed25519(现代、快速、透明) - 区块链:secp256k1(生态兼容) - 高安全:P-384 或 P-521 --- ## 参考资料 ### 标准与规范 ``` - NIST SP 800-56A:密钥协商建议 - NIST FIPS 186-4:数字签名标准(ECDSA) - RFC 8410:Ed25519 和 Ed448 算法 - RFC 8446:TLS 1.3(强制 ECDHE) - SEC 2:推荐椭圆曲线参数 ``` ### 工具与库 ``` Python: - cryptography: 现代密码学库 - PyNaCl: NaCl 的 Python 绑定(Ed25519) - ecdsa: 纯 Python ECDSA 实现 OpenSSL: - openssl genpkey -algorithm EC - openssl ecparam -list_curves SSH: - ssh-keygen -t ed25519 ``` ### 学习资源 ``` - 《Serious Cryptography》- Jean-Philippe Aumasson - 《Guide to Elliptic Curve Cryptography》- Hankerson 等 - SafeCurves:https://safecurves.cr.yp.to/ - Daniel J. Bernstein 的 Ed25519 论文 ``` ### 在线工具 ``` - Elliptic Curve Calculator: https://www.dcode.fr/elliptic-curves - Curve25519 在线演示:https://ed25519.cr.yp.to/ ``` --- *365 天信息安全技术系列 | Day 191 | 密码学系列第 11 篇* > ECC 以短密钥提供高安全性,是现代密码学的首选。 > 本文内容仅供学习和研究使用,请勿用于非法目的。 --- *本文是 365 天信息安全技术系列的第 191 篇,密码学系列第 11 篇* *密码学系列 11/30 完成!*
myh0st
2026年4月13日 23:19
分享文档
收藏文档
上一篇
下一篇
微信扫一扫
复制链接
手机扫一扫进行分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码