密码学之一 —— 三类算法
一、加密算法
1、对称加密算法 - AES-Advanced Encryption Standard
-
是什么?
AES 就是目前最流行、最安全的对称加密算法,简单说就是加密和解密用同一个密码。
📌 适用场景(生活 / 工作中常见)- 手机 / 电脑锁屏密码:你的手机开机密码,实际是用 AES 加密了手机数据;
- APP 本地数据存储:比如微信的聊天记录、支付宝的本地缓存,都是 AES 加密;
- 点对点保密传输:比如你给朋友传保密文件、公司内部系统的敏感数据传输;
- 物联网设备:智能门锁、摄像头的通信数据,用 AES 加密保证安全。
-
为什么?
术语- 明文、密文、密钥
- 密钥长度:长度越长,越安全,破解难度越大
AES-128:密钥长度 128 位(最常用,手机 / APP / 普通场景);
AES-192:密钥长度 192 位(中高安全场景,不常用);
AES-256:密钥长度 256 位(最高安全级别,银行 / 军工 / 政务)
-
加密流程
AES 不是简单的 “替换字符”,而是一套标准化的「搅乱流程」,可以理解为给明文做 3 轮 “花式搅乱”,最终变成密文,解密就是反向搅乱:- 分组:把明文切成固定大小的 “小块”(每块 128 位),就像把长纸条切成一段一段的;
- 搅乱:用密钥对每个小块做「替换、移位、混合」操作,把明文的字符顺序、内容彻底打乱;
- 拼接:把搅乱后的小块重新拼起来,就得到了密文。
✅ 重点:不管明文多长,AES 都会按固定规则分组处理,解密时反向操作即可,速度非常快,手机 / 电脑运行毫无压力。
-
加密模式
-
模式 1:ECB 模式(有坑,禁止使用)
💡 大白话:把明文分成小块,每一块用同一个密钥单独加密,就像把蛋糕切成小块,每块都抹同一种果酱。
❌ 缺点:如果明文里有重复的内容,加密后的密文也会重复,容易被攻击者找到规律,安全性低。
👉 适用场景:几乎不用,了解即可,面试会问到。 -
模式 2:CBC 模式(纯加密场景流行)
💡 大白话:加密前先加一个「初始向量(IV)」,每一块的加密结果会影响下一块,就像接力赛,前一棒的结果决定后一棒的起跑,彻底避免重复密文。
✅ 优点:安全性高,没有 ECB 的漏洞,是目前最常用的模式。
✅ 关键:CBC 模式需要两个东西:密钥 + 初始向量(IV),IV 是随机的,长度固定为16字节 - 128 位,不需要保密,但必须和密钥一起用。 -
模式 3:GCM 模式(加密 + 防篡改 + 防伪造)
💡 CBC 的「升级款」,AES-GCM 是带认证的流加密模式,大白话就是「加密数据的同时,生成一个 “防伪验证码”」,解密时先验这个验证码,验证码不对,直接拒绝解密(说明数据被改了 / 是伪造的),而且它是流加密、不用填充,速度比 CBC 还快,现在行业里基本都用 GCM 替代 CBC 了
核心三要素:AES-128 密钥 16位/24位/32位 + 12 字节唯一 IV(必选随机生成,可明文传)+16 字节 Tag(加密生成解密验证);
示例:- 你和朋友约定密钥:奶茶不加糖;
- 你用密钥加密明文「今晚 8 点 XX 餐厅聚餐」,生成密文 + 防伪验证码(Tag 16字节-128位)(比如密文:%@6&*ab9,Tag:123456);
- 你把「密文 + Tag」一起传给朋友;
- 朋友收到后,先用密钥验 Tag:
- ✅ Tag 对得上:说明数据没被改、不是伪造的,正常解密出明文;
- ❌ Tag 对不上:直接扔掉,不解密,知道数据被动手脚了。
-
区别:GCM 的 IV 为什么要求「唯一」而不是「随机」?
大白话理解:同一个密钥下,只要 IV 不重复,即使明文相同,加密后的密文和 Tag 也绝对不同;如果 IV 重复了,黑客能通过对比密文,直接破解出密钥,整个 GCM 加密就等于裸奔了。
而 CBC 的 IV 只要求随机,不强制唯一(重复了只是密文重复,不会直接泄露密钥),所以GCM 对 IV 的要求更严,但 12 字节的 IV 随机生成,重复的概率比中彩票还低,放心用。 -
适用场景:
- HTTPS/TLS:现在的浏览器和服务器通信(TLS1.2/TLS1.3),默认用 AES-GCM 加密,保证网页数据的保密和完整;
- 物联网设备:智能门锁、摄像头、手环的通信数据,GCM 速度快、轻量,还能防篡改(防止坏人伪造设备指令);
- 移动端 APP:微信 / 支付宝的聊天记录、支付数据,手机银行的交易数据,都用 GCM 加密;
- 金融 / 支付:银行卡交易、扫码支付的核心数据,加密的同时保证不被篡改;
- 大数据传输:流加密速度快,适合大文件 / 大流量数据的加密传输,无填充省步骤。
-
2、非对称加密
-
是什么?
非对称加密的核心是公钥(Public Key)+ 私钥(Private Key) 成对生成,这对钥匙是 “数学绑定” 的 ——公钥加密的内容,只有对应的私钥能解密;私钥签名的内容,只有对应的公钥能验签,反之亦然,而且从公钥推不出私钥,这是安全的核心。- 加密 / 解密:公钥加密,私钥解密(核心解决 “密钥安全传输” 问题,配合 AES 用);
- 签名 / 验签:私钥签名,公钥验签(核心解决 “防抵赖、防篡改”,比如签合同,你用私钥签,别人用你的公钥验,证明是你签的,不是别人伪造的)。
- 缺点:非对称加密从不直接加密大文件 / 大文本(速度太慢),实际项目中都是非对称加密 + 对称加密结合用(非对称加密 AES 密钥,AES 加密实际数据),这是行业标配!
-
有对称加密为什么还要非对称加密?
对称加密使用一把钥匙通加解密,但它有个致命痛点:密钥没法安全传给对方(传的过程中容易被截获),而非对称加密就是专门解决这个问题的 —— 核心是生成一对钥匙(公钥 + 私钥),公钥随便给人,私钥自己藏好,加密 / 解密、签名 / 验签用不同的钥匙,完美解决密钥传输和身份认证问题。
非对称加密的解决方案(公钥随便传,私钥自己藏)- 朋友先生成一对钥匙:私钥(自己藏在口袋里,绝对不给人)+ 公钥(写在纸上,贴在大街上,谁都能拿);
- 你拿朋友的公钥,把 AES 密钥 “奶茶不加糖” 加密成乱码,传给朋友;
- 坏人就算截获了乱码,也只有朋友的私钥能解密,拿到真正的 AES 密钥;
- 你和朋友用解密后的 AES 密钥,加密聚餐纸条(非对称加密速度慢,一般不直接加密大内容,只加密 AES 密钥,这是行业通用玩法!)。
-
分类
目前主流的非对称加密算法分两类:- 一类是加密 + 签名都能做的通用型(RSA、ECC),RSA 是老大哥(兼容性拉满),ECC(椭圆曲线)是新主流(更安全、更轻量,现在首选);
- 一类是只做签名 / 验签的专用型(DSA、ECDSA),ECDSA 替代了老旧的 DSA,是目前数字签名的标配。
(1)ECC(椭圆曲线加密,Elliptic Curve Cryptography)—— 新主流,首选!
ECC 是目前最推荐的非对称加密算法,也是未来的趋势,核心基于椭圆曲线离散对数难题),最大的优势是:同样的安全级别下,ECC 的密钥长度比 RSA 小得多,速度更快、更轻量,特别适合移动端、物联网、区块链等对性能 / 存储空间有要求的场景。- 对比 RSA:
- 256 位的 ECC 密钥 ≈ 2048 位的 RSA 密钥(安全级别基本一致);
- 密钥小:256 位 ECC 密钥比 2048 位 RSA 密钥小近 10 倍,存储 / 传输更方便;
- 速度快:加解密 / 签名验签的速度比 RSA 快 2-5 倍,移动端 / 物联网设备跑起来毫无压力。
- 常用密钥长度
- 256 位(主流,大部分场景够用,手机 / APP / 物联网 / HTTPS);
- 384 位(高安全场景,金融 / 政务);
- 521 位(最高安全级别,军工 / 核心机密)。
- 适用场景(现在的主流,能选 ECC 就不选 RSA)
- HTTPS/TLS1.3(现在浏览器默认用 ECC 握手,替代 RSA);
- 移动端 APP(微信 / 支付宝 / 手机银行的身份认证、签名);
- 物联网(智能门锁 / 摄像头 / 手环的密钥协商、签名);
- 区块链(比特币 / 以太坊的钱包地址、交易签名,用的是 ECC 的 secp256k1 曲线);
- 数字证书(新申请的 SSL 证书,基本都是 ECC 类型,比 RSA 证书小);
- 轻量级设备(单片机 / 传感器,存储空间小,跑不动大的 RSA 密钥)。
(2)RSA-老大哥,兼容性拉满
RSA 是最经典的非对称加密算法,由三位数学家发明(Rivest+Shamir+Adleman),名字就是三人首字母,核心基于大质数分解难题—— 大白话就是:“把两个超大的质数乘起来得到一个数,很容易;但反过来,把这个大数分解成两个原始质数,极难”,目前 2048 位以上的 RSA 密钥,全世界的计算机都无法暴力破解。
RSA 是过去几十年的非对称加密 “扛把子”,兼容性无敌,所有系统 / 编程语言 / 设备都支持,现在虽然被 ECC 赶超,但老系统 / 老设备还在广泛使用,是 “兜底选择”。
- 常用密钥长度
- ❌ 1024 位:2015 年后就被证明可以被破解,绝对不能用!
- 2048 位(主流,老系统 / 兼容性要求高的场景);
- 4096 位(高安全场景,金融 / 政务,不推荐用,密钥大、速度慢,不如用 256 位 ECC);
- 核心特点
- 优点:兼容性无敌,任何设备 / 语言都支持,开发不用考虑适配问题;
- 缺点:密钥大、速度慢,2048 位 RSA 的加解密速度比 256 位 ECC 慢很多,不适合轻量级设备。
- 适用场景
- 老系统 / 老设备的密钥协商、加密(比如传统金融系统、旧版服务器);
- 兼容性要求极高的场景(比如需要适配各种老旧终端的系统);
二、哈希算法
哈希算法(Hash Algorithm)是密码学和数据处理的基础工具,它不等同于加密算法 —— 它无密钥、不可逆、把任意长度数据变成固定长度的哈希值,核心作用是做数据指纹、完整性校验、密码存储,是加解密体系的 “黄金辅助”,但绝对不是加密算法(加密算法是可逆的)。
-
是什么?
任意长度的原始数据(小到一个字符,大到几个 G 的文件),通过哈希算法,计算出一个固定长度、唯一的字符串(哈希值 / 散列值 / 摘要),这个哈希值就像数据的 “数字指纹”—— 指纹能唯一标识人,哈希值能唯一标识原始数据(理想状态)。
核心特点:- 固定长度:输入任意长,输出都一样长
- 正向快速:计算哈希值快,反向推不出原始数据
- 雪崩效应:输入改一点,哈希值全变
- 抗碰撞性:不同输入,几乎不可能算出相同哈希值
-
哈希算法的实际应用
-
应用 1:密码存储(最核心的安全场景,绝对不能存明文)
这是哈希算法最经典的应用 ——网站 / APP 绝对不会存储你的明文密码,只会存储密码的哈希值,这是行业铁律。- 核心流程(以 SHA-256 + 加盐为例)
- 你注册账号,输入密码123456;
- 服务器生成一个随机的盐值(Salt)(比如abc123),把密码 + 盐值拼接(123456abc123);
- 服务器用 SHA-256 计算拼接后的数据的哈希值,得到f987654321abcdef...;
- 服务器只存储盐值和哈希值,不存储任何明文密码;
- 你登录时,输入密码123456,服务器用相同的盐值拼接,计算哈希值,和存储的哈希值对比 —— 相同则登录成功,不同则失败。
- 关键:为什么要 “加盐”?
防止彩虹表破解—— 黑客会提前计算出大量常见密码的 MD5/SHA-256 哈希值,做成 “彩虹表”,如果密码不加盐,黑客可以通过哈希值反向匹配出明文密码;加盐后,哪怕是常见密码,哈希值也会完全不同,彩虹表彻底失效。✅ 示例:密码123456的 SHA-256 哈希值是固定的,但加盐abc123后,哈希值就变了,加盐def456后,哈希值又变了,每个用户的盐值都不同,彻底防彩虹表。 - 为什么不用加密存储密码?
加密是可逆的,如果服务器的加密密钥泄露,黑客可以解密出所有用户的明文密码;而哈希是不可逆的,哪怕哈希值泄露,黑客也推不出明文密码,安全性更高。
- 核心流程(以 SHA-256 + 加盐为例)
-
应用 2:数字签名的 “前置步骤”(和非对称加密配合,核心)
之前讲非对称加密的签名 / 验签时,提到 “非对称加密从不直接加密大数据”,数字签名也是如此 ——不会直接用私钥对原始数据签名,而是先对原始数据做哈希,再用私钥对哈希值签名,哈希在这里起到 “压缩数据、保证完整性” 的核心作用。- 数字签名完整流程(ECC 私钥 + SHA-256,行业标配)
- 哈希的核心作用
- 压缩数据:把大数据变成 64 个字符的哈希值,非对称签名速度提升上万倍;
- 保证完整性:如果合同被篡改,哪怕改一个字,哈希值就会全变,验签必然失败,无法伪造。
✅ 这是哈希 + 非对称加密的经典配合,也是 HTTPS、电子合同、区块链签名的核心原理。
-
应用 3:数据完整性校验(生活中最常见,比如下载文件 / 传文件)
- 你下载软件、电影、安装包时,网站会给出一个哈希值(如 SHA-256),这就是用哈希算法做数据完整性校验,防止文件被篡改、被植入病毒;
- 网盘 / U 盘传文件:怕文件损坏,计算哈希值对比,确认文件完整;
- 区块链区块校验:每个区块链区块都包含上一个区块的哈希值,一旦某个区块被篡改,后续所有区块的哈希值都会变,全网节点校验会失败,保证区块链的不可篡改。
-
应用 4:区块链的 “核心基石”(哈希 + 加密的极致结合)
区块链的不可篡改、去中心化特性,完全基于哈希算法的特性,以比特币为例:- 区块哈希:每个区块包含交易数据、时间戳、上一个区块的哈希值,用 SHA-256 计算出当前区块的哈希值 —— 如果修改区块内的任何交易数据,区块哈希值会全变,后续所有区块的哈希值也会变,全网节点会拒绝这个篡改后的区块;
- 交易哈希:每笔比特币交易都用 SHA-256 计算哈希值,唯一标识一笔交易,防止交易被伪造;
- 钱包地址:比特币的钱包地址,是通过 ECC 公钥做 SHA-256+RIPEMD160 哈希计算后得到的,不可逆,保证钱包地址的安全。
-
应用 5:普通数据处理(非安全场景,哈希表 / 数据索引)
哈希算法不仅用于密码学,还用于普通的程序开发,比如编程语言中的哈希表(HashMap/HashTable),核心是用哈希算法计算数据的哈希值,作为数据的索引,实现O (1) 时间复杂度的增删改查,提升程序效率。
示例:Java 中的HashMap,用键(Key)的哈希值计算存储位置,快速找到值(Value);
特点:这里用的哈希算法(如 Java 的 Object.hashCode ())是非安全型的,不要求抗碰撞性,只要求计算速度快,和密码学哈希算法不同。
-
1、SHA-2 家族(安全型,必用)
SHA(Secure Hash Algorithm,安全哈希算法)是美国 NIST 发布的标准,SHA-2 家族是目前全球最主流、最安全的哈希算法,彻底替代了 MD5 和 SHA-1,分为 SHA-224、SHA-256(首选)、SHA-384、SHA-512等,数字代表哈希值的位数,其中SHA-256是绝对主流,覆盖 99% 的安全场景。
-
SHA-256
任意长度(0 ~ 2^64-1 位)的原始数据(小到 1 个字符,大到 10G 文件),通过固定的算法规则转换为256 位(32 字节)的固定长度二进制哈希值,开发中最常用64 个十六进制字符表示(1 个十六进制字符 = 4 位二进制,64×4=256 位)。 -
SHA256 计算流程
- 步骤 1:数据预处理 —— 补位 + 记录原始长度
SHA256 的后续计算要求输入数据必须是512 位的整数倍(这是算法设计的固定规则),如果原始数据长度不是 512 位的倍数,会先进行补位,同时记录原始数据的真实长度,保证计算的唯一性,两步走:- 补 1 加 0:在原始数据的二进制末尾,先加1 个二进制位1,再连续加若干个二进制位0,直到数据长度模 512 等于448 位(预留 64 位用于记录原始长度);
- 加原始长度:将原始数据的真实长度(以位为单位)转换为64 位二进制数,拼接到补位后的数据末尾,此时数据长度恰好是 512 位的整数倍。
简单示例:输入123(二进制长度 24 位)
先补 1 个1 + 423 个0,使长度达到 448 位;
再拼接 64 位的原始长度24,最终总长度为 512 位(1 个 512 位块)。
- 步骤 2:初始化哈希常量 ——8 个固定的 32 位值
SHA256 的最终哈希值是由8 个 32 位的二进制数拼接而成的(8×32=256 位),计算前会先初始化8 个固定的初始哈希常量(H0~H7)。
这些常量是由 NIST 规定的固定值(基于自然常数 e 和质数的平方根计算而来),所有平台、所有语言的 SHA256 实现都使用这组常量,这是 “同一输入全球结果唯一” 的重要保证,开发无需记忆,库都已内置:
plaintext
H0 = 0x6a09e667 H1 = 0xbb67ae85 H2 = 0x3c6ef372 H3 = 0xa54ff53a
H4 = 0x510e527f H5 = 0x9b05688c H6 = 0x1f83d9ab H7 = 0x5be0cd19
(0x表示十六进制,每个常量 32 位) - 步骤 3:分块处理 + 64 轮压缩 —— 核心计算过程
将预处理后的 512 位整数倍数据,按 512 位为 1 个块进行拆分,然后对每个块执行 64 轮固定的压缩计算,直到所有块处理完毕,核心过程:
消息扩展:对当前 512 位的块,通过固定规则生成64 个 32 位的临时字(W0~W63),作为 64 轮计算的输入;
64 轮位运算:用初始化的 8 个常量(H0~H7)作为初始值,结合 64 个临时字,执行64 轮固定的位运算(包括加、异或、旋转、移位、选择等),每一轮都会更新 8 个常量的值;
块间累加:一个 512 位块处理完成后,将更新后的 8 个常量与上一个块的计算结果进行加和,作为下一个块的初始值;
循环处理:重复上述步骤,直到所有 512 位块处理完毕。 - 步骤 4:拼接结果 —— 生成最终的 256 位哈希值
所有 512 位块处理完成后,会得到最终的 8 个 32 位常量(H0~H7),将这 8 个常量按顺序拼接,得到一个256 位的二进制数,再将其转换为64 个十六进制字符,就是我们最终看到的 SHA256 哈希值。
✅ 核心总结:SHA256 的计算过程是固定、公开、无随机因素的,这也是它能成为全球通用标准的根本原因。
- 步骤 1:数据预处理 —— 补位 + 记录原始长度
2、区块链专用:Keccak-256(SHA-3 的核心)
Keccak-256 是基于Keccak 算法实现的 256 位哈希算法,是NIST(美国国家标准与技术研究院)选定的 SHA-3 标准核心实现(SHA-3 是哈希算法标准,Keccak 是该标准的底层算法),核心作用是将任意长度(0 ~ 2^1600 位)的原始数据转换为256 位(32 字节)的固定长度哈希值,开发中常用64 个十六进制字符表示(和 SHA256 输出格式一致)。
但是Keccak-256 ≠ SHA3-256(开发最易踩坑)。
-
核心特点
- 基于海绵函数结构,灵活性远超 SHA256
SHA256 采用分块压缩结构(固定 512 位分块,多轮压缩),而 Keccak-256 采用海绵函数结构(Sponge Function),核心是吸收(Absorb)+ 挤压(Squeeze)两个阶段,可灵活适配任意长度输入(0 ~ 2^1600 位)、任意长度输出,不仅能生成 256 位哈希,还能生成 128/512 位哈希,满足区块链不同场景的需求(如以太坊的交易哈希 256 位,部分签名哈希 128 位)。 - 天生抗量子计算攻击,未来安全保障
这是 Keccak-256 最核心的优势!SHA256 基于大质数分解 / 离散对数难题,量子计算机可通过Shor 算法快速破解;而 Keccak-256 基于海绵函数的位置换 / 混淆,量子计算机暂无有效攻击算法,是量子时代的安全哈希算法,以太坊选择它也是为了应对未来的量子计算威胁。
- 基于海绵函数结构,灵活性远超 SHA256
-
使用场景:
- 应用 1:以太坊钱包地址生成(核心场景,开发必知)
- 应用 2:以太坊交易 / 区块哈希生成(共识核心)
- 应用 3:以太坊智能合约地址生成(部署核心)
- 应用 4:以太坊智能合约中的哈希计算(Solidity 开发)
- 应用 5:以太坊签名验签的前置步骤(和非对称加密配合)
-
选型建议
- 以太坊 / 智能合约开发:必选 Keccak-256(以太坊专属,Solidity 原生支持);
- 比特币 / 传统区块链开发:选SHA256(比特币专属,原生库支持);
- 传统项目 / 非区块链开发:选SHA256(原生库支持,开发成本低);
- 量子安全需求的新项目:选Keccak-256(天生抗量子,未来兼容);
-
Keccak-256 计算流程:海绵函数的「吸收 + 挤压」
核心前置:海绵函数的基本逻辑
海绵函数就像一块海绵吸水再挤水:-
吸收阶段:把任意长度的输入数据 “吸进” 算法的状态矩阵,逐步更新矩阵状态;
-
挤压阶段:从更新后的状态矩阵中 “挤出” 固定长度的输出数据(即哈希值);
核心特点:输入可长可短,输出也可长可短,灵活性远超 SHA256 的固定分块结构。 -
步骤 1:数据预处理 —— 以太坊定制的「101」填充规则(最关键)
Keccak-256 的预处理只有一步填充,且以太坊有定制化规则,这是和标准 SHA3-256、SHA256 最大的区别,开发中必须严格遵循,否则哈希值会错误!
定分块大小:Keccak-256 的输入分块大小为1088 位(由算法参数决定:容量 = 512 位,速率 = 1088 位,总状态 = 1600 位 = 5x5x64);
以太坊填充规则(101):在原始数据的二进制末尾,先补 1 个二进制位1,再连续补若干个二进制位0,直到数据长度成为1088 位的整数倍,无任何后缀(标准 SHA3-256 会在最后补11101,以太坊直接省略);
✅ 示例:输入空字符串""(0 位),补 1 个1 + 1087 个0,总长度为 1088 位(1 个分块);
✅ 示例:输入123(24 位),补 1 个1 + 1063 个0,总长度为 1088 位。 -
步骤 2:初始化状态矩阵 ——5x5x64 位的全 0 矩阵
Keccak-256 的核心计算载体是5x5x64 位的三维状态矩阵(共 5564=1600 位),计算前将矩阵所有位初始化为0,作为初始状态。 -
步骤 3:吸收阶段 —— 逐块更新状态矩阵
将预处理后的 1088 位整数倍数据,按 1088 位为 1 个分块进行拆分;
对每个分块,执行位运算混淆后,将分块数据 “吸收” 到 5x5x64 的状态矩阵中,更新矩阵的位状态;
重复上述步骤,直到所有分块都被吸收,此时状态矩阵的状态已完全由输入数据决定。 -
步骤 4:挤压阶段 —— 生成 256 位哈希值(以太坊固定输出)
吸收阶段完成后,从最终的 5x5x64 状态矩阵中,按顺序提取前 256 位二进制数据;
将这 256 位二进制数据转换为64 个十六进制字符,就是以太坊专用的 Keccak-256 哈希值。
✅ 核心总结:Keccak-256 的计算流程核心是海绵函数的吸收 + 挤压,开发中唯一需要关注的是以太坊的 10*1 填充规则,确保使用的第三方库是以太坊定制版 Keccak-256,而非标准 SHA3-256。
-
-
开发实现
和SHA256不同,几乎所有语言都没有原生的 Keccak-256 库,需要引入第三方密码学库(如 Java 的 BouncyCastle、Python 的 pycryptodome),且必须确保使用的是以太坊定制版(10*1 填充),而非标准 SHA3-256
三、签名算法
数字签名算法不是单独的算法,而是 **「哈希算法 + 非对称加密」的组合体 **,核心解决传统签名的「易伪造、难验证、可抵赖」问题,是现代密码学的核心应用,也是区块链、电子合同、HTTPS、智能合约的安全基石
-
数字签名是什么?
- 手写签名:在纸质文件上签字,证明是本人操作,但易伪造、易抵赖;
- 数字签名:用非对称加密的私钥对「数据的哈希值」进行加密得到的一串字符,相当于「电子手写签名」,仅能由私钥持有者生成,所有人可通过公钥验证,无法伪造、无法抵赖;
- 和加密区别:数字签名≠非对称加密(加密是「公钥加密私钥解」,签名是「私钥加密哈希值,公钥解密验证」),且签名必须结合哈希算法(避免直接对大数据加密,提升效率)。
数字签名的本质是「用私钥对数据的哈希值做加密,用公钥解密验证哈希一致性」,哈希解决「大数据效率低」问题,非对称加密解决「防抵赖、防伪造」问题
-
数字签名的 3 个核心价值
- 防抵赖:仅私钥持有者能生成签名,一旦生成,无法否认是本人操作(如区块链交易签名,无法否认是自己发起的);
- 防篡改:数据只要被修改,哈希值就会全变,验签必然失败(如电子合同改一个字,签名就失效);
- 防伪造:没有私钥,无法生成能通过公钥验证的签名(如伪造你的区块链签名,全网节点验签会直接拒绝)。
-
数字签名的通用流程
-
签名端(生成签名)
核心原则:私钥仅由签名者持有,绝对不泄露,步骤如下:- 准备原始数据:待签名的文件 / 字符串 / 接口参数(任意长度,如电子合同、区块链交易、接口请求);
- 计算数据哈希:用哈希算法(SHA256/Keccak-256/SM3)对原始数据计算哈希值,得到固定长度的小数据(如 SHA256→64 个十六进制字符);
✅ 关键:绝对不能直接对原始大数据签名,非对称加密对大数据操作速度极慢,哈希是「压缩数据」的核心; - 私钥签名哈希值:用签名者的非对称私钥(ECC/RSA/SM2 私钥)对哈希值进行签名运算,生成签名结果(不同算法的签名格式不同,如 ECDSA→r+s,RSA→字节数组);
- 传输数据 + 签名:将「原始数据 + 签名结果 + 使用的哈希算法」一起发送给验签端(哈希算法需约定,保证验签端和签名端一致)。
-
验签端(验证签名)
核心原则:公钥可以公开传播,任何人都能获取,步骤如下:- 接收数据:收到「原始数据 + 签名结果 + 哈希算法约定」;
- 重新计算哈希:用和签名端完全一致的哈希算法,对原始数据重新计算哈希值,得到「验签端哈希值」;
✅ 关键:哈希算法必须一致(如签名用 SHA256,验签不能用 Keccak-256),否则哈希值必然不同,验签失败; - 公钥验签解哈希:用签名者的非对称公钥(和私钥配对)对「签名结果」进行验签运算,解出「签名端哈希值」;
✅ 关键:如果签名是伪造的 / 被篡改的,此步骤会直接抛出异常 / 返回空; - 对比哈希值:将「验签端哈希值」和「签名端哈希值」进行对比:
- ✅ 一致:签名有效→数据是签名者发的、未被篡改、签名未伪造;
- ❌ 不一致 / 验签异常:签名无效→数据被篡改 / 签名是伪造的 / 公钥不匹配。
验签的本质:验签不验证数据的保密性,只验证「数据是否是指定人发的」和「数据是否被篡改」—— 这是数字签名和加密的核心区别,加密是为了「让别人看不懂」,签名是为了「让别人相信是你发的、没被改」。
-
算法 1:ECDSA(椭圆曲线数字签名算法)—— 现在的绝对主流
ECDSA(Elliptic Curve Digital Signature Algorithm)是基于 ECC 椭圆曲线非对称加密的签名专用算法,也是目前全球使用最广泛的数字签名算法,彻底替代了老旧的 DSA,是区块链、移动端、HTTPS、智能合约的标配。
- ECDSA 目前有两种主流的行业标准曲线:
- secp256r1(NIST P-256):通用场景标配(HTTPS、移动端、传统开发),兼容性无敌,搭配SHA256哈希;
- SECP256K1:区块链专属曲线,是以太坊 / 比特币的唯一签名算法,搭配Keccak-256哈希。
- 针对比特币:搭配双SHA256哈希[SHA256(SHA256(原始数据))],签名结果:r + s, 各32字节,共64字节。
- 针对以太坊:搭配Keccak256哈希,签名结果:r + s + v,分别是32字节、32字节、1字节共65字节;
- R、S、V含义
- R:32 字节,椭圆曲线上随机点 P 的 x 坐标,签名的 “随机基准”,验签核心锚点,比特币 / 以太坊均有,格式完全一致;
- S:32 字节,私钥、哈希值、R 共同计算出的核心签名值,签名的 “验证凭证”,绑定私钥与哈希,比特币 / 以太坊均有,以太坊会额外调整 S 到 “低半阶”
- V:1 字节,恢复标识(Recovery ID),值为 27/28 或 0/1,确定随机点 P 的 y 坐标符号,用于恢复公钥 / 地址,比特币无,以太坊独有(因以太坊交易不附带公钥,需从签名恢复)
算法2:Ed25519
Ed25519 是基于爱德华曲线(Edwards Curve)的椭圆曲线数字签名算法,属于EdDSA(爱德华曲线数字签名算法)家族的核心实现,是目前密码学领域的新一代主流签名算法—— 它解决了 ECDSA-secp256k1 的诸多痛点(如依赖安全随机数、易受侧信道攻击、效率偏低),兼具更高的安全性、更快的运算速度、更简洁的密钥 / 签名格式,目前已广泛应用于 Solana/Cardano 等区块链、SSH/TLS1.3、Signal 加密通信、Docker 等场景,是替代 ECDSA-secp256k1 的重要选择。核心作用是用 32 字节私钥生成 32 字节公钥,对任意长度消息生成 64 字节签名,实现高效、安全的数字签名,无随机数依赖、天生抗侧信道攻击是其核心亮点。
-
核心设计
Ed25519 的底层是Curve25519(2005 年设计的椭圆曲线),这是一条专为密码学优化的曲线,而 Ed25519 是将 Curve25519 转换为爱德华曲线形式后实现的签名算法(蒙哥马利曲线适合密钥交换,爱德华曲线适合签名,二者可互相转换,公私钥通用)。- Curve25519:主打密钥交换(如 WireGuard、SSH 的密钥协商),无专利、无授权限制;
- Ed25519:主打数字签名,基于 Curve25519 的爱德华形式,继承其所有优势,是签名场景的最优实现。
-
对比DCDSA-secp256k1
- ✅ 无随机数依赖,彻底避免 k 泄露 / 重复的致命坑
ECDSA-secp256k1 的最大痛点是依赖安全随机数 k:加签时若 k 被泄露 / 重复使用,攻击者可直接推导出私钥(区块链历史上曾出现过因 k 重复导致的私钥泄露事件),因此开发中必须用密码学安全随机数生成器,且需严格保证 k 的唯一性。
而 Ed25519完全无需随机数:加签时的所有随机化参数均由私钥通过 SHA-512 确定性派生,无需额外生成随机数,从算法层面彻底规避了 k 泄露 / 重复的风险,开发中无需关注随机数生成,大幅降低踩坑概率。 - ✅ 天生抗侧信道攻击,硬件 / 嵌入式场景更安全
侧信道攻击:攻击者通过收集算法运行时的物理信息(如 CPU 运算时间、功耗、电磁辐射)推导出私钥,ECDSA 因运算步骤的时间 / 功耗不一致,易受此类攻击,开发中需做额外的工程优化(如恒时运算)才能防护。
Ed25519 的算法设计采用全恒时运算,所有运算步骤的时间、功耗完全一致,天生抗侧信道攻击,无需开发额外防护,特别适合智能门锁、物联网设备、区块链矿机等硬件 / 嵌入式场景。 - ✅ 效率极致,加签验签速度比 ECDSA 快 2-3 倍
ECDSA-secp256k1 的加签验签涉及模逆元、大整数乘法等复杂运算,步骤多、耗时久;而 Ed25519 基于爱德华曲线的加法 / 乘法公式优化,取消了模逆元运算,且内置的 SHA-512 哈希运算为硬件优化的高速算法,加签速度比 ECDSA 快 2 倍,验签速度快 3 倍,批量验签时优势更明显(如 Solana 的 TPS 达 5 万 +,核心原因之一是采用 Ed25519)。 - ✅ 密钥 / 签名格式极简,开发无冗余处理
ECDSA-secp256k1 的公钥有 64 字节(无压缩)/33 字节(压缩) 两种格式,无压缩公钥需带 04 前缀,签名后的 R/S 需补零到 32 字节,以太坊还需扩展 V 字段,开发中需做大量格式处理;
而 Ed25519 的私钥 32 字节、公钥 32 字节、签名 64 字节是算法硬编码的固定格式,无任何前缀、无压缩 / 无压缩之分,签名的 R/S 天然 32 字节,开发中无需做格式补零、前缀裁剪,直接传输 / 存储即可,大幅降低开发成本。 - ✅ 内置哈希算法,避免两端哈希不一致的坑
ECDSA 是签名算法与哈希算法解耦的,开发中需提前约定哈希算法(如比特币用双 SHA256,以太坊用 Keccak-256),若签名端和验签端的哈希算法不一致,会导致验签失败;
Ed25519 将SHA-512 哈希算法内置到算法核心,加签时自动对私钥和消息做 SHA-512 哈希,开发中无需手动计算哈希、无需约定哈希算法,从算法层面避免了哈希不一致的开发坑。
- ✅ 无随机数依赖,彻底避免 k 泄露 / 重复的致命坑
-
Ed25519 核心前置:密钥对生成流程
Ed25519 的私钥是32 字节种子,公钥由种子通过SHA-512 哈希 + 椭圆曲线运算派生,全程确定性生成(同一种子始终生成同一对公钥私钥)。- 生成 32 字节随机种子:用密码学安全随机数生成器(如 JavaSecureRandom、Pythonsecrets)生成 32 字节随机数,作为 Ed25519 的种子(对外称私钥),这是开发者唯一需要生成的随机数;
- 种子 SHA-512 哈希:对 32 字节种子执行SHA-512 哈希,得到 64 字节的哈希值;
派生签名私钥与掩码:将 64 字节哈希值分为前 32 字节和后 32 字节: - 前 32 字节:做模 q 运算 + 格式修正(将第 255 位设为 0,第 254 位设为 1),得到真正的签名私钥(记为 sk),仅参与加签运算,不对外暴露;
- 后 32 字节:作为掩码(记为 prefix),参与消息哈希的混合运算,提升签名安全性;
- 生成公钥:用签名私钥 sk 与 Ed25519 的基点 B执行椭圆曲线标量乘法,得到曲线上的点P = sk * B,将点 P 转换为32 字节的字节串,即为 Ed25519 的公钥(pk),可公开传播;
- 输出密钥对:对外暴露32 字节种子(私钥)+32 字节公钥,这是开发中使用的密钥对。
-
加签 & 验签完整流程
- 加签侧:持有32 字节种子(私钥)+32 字节公钥,输入任意长度待签名消息,输出64 字节签名(R+S 各 32 字节);
- 验签侧:持有32 字节公钥,输入待验证消息 + 64 字节签名,输出验签结果(成功 / 失败);
- 签名格式:64 字节签名由 R(32 字节)+S(32 字节) 组成,R 是椭圆曲线上的点转换的字节串,S 是核心验证参数,无任何扩展字段(如 ECDSA 的 V 字段)。
-
开发库
- Java 引入BouncyCastle库,python cryptography库

浙公网安备 33010602011771号