ECC(Elliptic Curve Cryptography,椭圆曲线密码学)非对称加密算法介绍
- 一、签名文件
- 二、ECC签名文件验证流程
-
- [2.1 生成密钥对](#2.1 生成密钥对)
-
- [OpenSSL 命令行生成ECC 密钥对](#OpenSSL 命令行生成ECC 密钥对)
- [步骤 1:生成 256 位 ECC 私钥](#步骤 1:生成 256 位 ECC 私钥)
- [步骤 2:从私钥提取 256 位 ECC 公钥](#步骤 2:从私钥提取 256 位 ECC 公钥)
- [步骤 3:验证密钥长度(关键!确认是 256 位)](#步骤 3:验证密钥长度(关键!确认是 256 位))
- [2.2 生成摘要](#2.2 生成摘要)
-
- [1. 基础用法](#1. 基础用法)
- [2. 生成十六进制摘要](#2. 生成十六进制摘要)
- [3. 将摘要保存到文件](#3. 将摘要保存到文件)
- [2.3 使用私钥对摘要进行签名](#2.3 使用私钥对摘要进行签名)
-
- [1. 先生成摘要,再单独签名(灵活可控)](#1. 先生成摘要,再单独签名(灵活可控))
-
- [步骤 1:生成文件的 SHA-256 二进制摘要](#步骤 1:生成文件的 SHA-256 二进制摘要)
- [步骤 2:用私钥对二进制摘要签名](#步骤 2:用私钥对二进制摘要签名)
- [2. OpenSSL 快速生成签名](#2. OpenSSL 快速生成签名)
-
- [步骤 1:用 ECC 私钥对文件签名](#步骤 1:用 ECC 私钥对文件签名)
- [步骤 2:验证签名是否生成成功](#步骤 2:验证签名是否生成成功)
- [3. ECC签名文件的内容](#3. ECC签名文件的内容)
- [2.4 验证签名](#2.4 验证签名)
- 三、名称解释:
什么是ECC?
ECC 是 椭圆曲线密码学 的缩写。它是一种现代的非对称加密算法。
- 优势 :与传统的RSA算法相比,ECC能用更短的密钥长度提供同等级甚至更高的安全性 。
- 例如:一个256位的ECC私钥,其安全性约等于一个3072位的RSA密钥。这意味着计算更快、存储更小、带宽需求更低,特别适合移动设备、物联网和区块链等场景。
- 基础:它的安全性建立在"椭圆曲线离散对数问题"的数学难题上。简单理解就是:在椭圆曲线上进行特定的点运算很容易,但反过来想从结果和公开信息中求出初始的随机数(私钥)在计算上是不可行的。
ECC 和 RSA 都是最主流的非对称加密算法,但它们在设计、效率和应用上有着显著区别。
核心区别一览表
| 特性维度 | RSA | ECC | 优势方 |
|---|---|---|---|
| 数学基础 | 大整数质因数分解难题 | 椭圆曲线离散对数难题 | - |
| 密钥长度 | 长(通常 2048-4096 位) | 极短(通常 256-521 位) | ECC |
| 安全强度比 | 较低 | 非常高 | ECC |
| 计算速度 | 加密/解密较慢,签名慢 | 加密/解密较快,签名极快 | ECC |
| 验签逻辑 | 公钥运算结果 = 重新计算的摘要 | 公钥运算结果的 x 坐标 = 签名中的 r |
- |
| 带宽与存储 | 占用多(密钥和签名大) | 占用极少(密钥和签名小) | ECC |
| 资源消耗 | CPU和内存消耗高 | CPU和内存消耗低 | ECC |
| 成熟度与普及 | 极高(40+年历史,广泛部署) | 高(30+年历史,已成为新标准) | RSA |
| 标准化与兼容性 | 极其广泛(几乎无处不在) | 广泛(现代系统均支持) | RSA |
| 主要应用场景 | SSL/TLS 证书、传统数字签名、加密少量数据 | 移动设备、物联网、区块链、现代TLS、资源受限环境 | - |
两者在密钥长度与安全强度上的差异:ECC效率碾压
这是最直观的区别。为了达到相同的安全级别,ECC需要的密钥长度远小于RSA。
| 安全级别 (比特) | RSA 密钥长度 | ECC 密钥长度 |
|---|---|---|
| 80-bit | 1024 位 | 160 位 |
| 112-bit | 2048 位 | 224 位 |
| 128-bit | 3072 位 | 256 位 |
| 192-bit | 7680 位 | 384 位 |
| 256-bit | 15360 位 | 521 位 |
- 解释 :一个 256 位的 ECC 密钥 (如
secp256k1,比特币使用)提供的安全性,大致相当于一个 3072 位的 RSA 密钥。 - 结果:更短的密钥意味着更少的存储空间、更快的计算速度和更低的网络带宽消耗。
一、签名文件
签名文件(Signature file) :是用来验证文件完整性、真实性和来源的数字证明文件。它通常与原始文件一起提供,确保文件在传输或存储过程中未被篡改,并确认文件的发布者身份。
数字签名 是基于 非对称加密 + 哈希算法 的电子签名技术。
数字签名使用流程:
- 发送者用 私钥 对原始文件的摘要(digest)进行"加密",得到 数字签名 。
- 接收者收到原文件和签名后,使用收到的原文件计算得到摘要,加上 公钥 去验证签名。如果匹配,证明原文件没被篡改,且确实来自持有私钥的人 。
在非对称加密算法中,常见的是RSA 和 ECC 两种,在验证签名的过程中,两种加密算法的所采用的方式有所区别。其中,RSA的签名文件是对摘要进行加密后的文件,而ECC的签名文件不会包含摘要相关的信息,只包含用于验证签名是否合法的相关数字凭证。
两种签名机制的区别
RSA 签名
- 形式像:私钥加密摘要
- 验签像:公钥解密出摘要
- 结果:1 个大整数
ECC(ECDSA)签名
- 不是加密!不是加密!不是加密!
- 是椭圆曲线数学运算
- 结果:一对整数 r + s
- 无法从签名里还原出摘要
二、ECC签名文件验证流程
当下载固件时,我们还会附带上签名文件,用来验证固件的来源,防纂改。在下载固件的过程中,如果设备受到外部的攻击,下载的固件可能会被黑客纂改,更新程序的流程中,若没有签名验证过程,那么就无法防止这个攻击。加上固件签名验证,则可以在升级过程中,对固件的来源进行确认,未知来源的固件会被丢弃,从而规避了纂改攻击。
2.1 生成密钥对
下面使用 openssl 命令工具,生成 256 bit 的ECC 密钥对。
OpenSSL 命令行生成ECC 密钥对
256 位 ECC 密钥对的核心是选择 prime256v1(别名 secp256r1)曲线 ------ 这是业界标准的 256 位 ECC 曲线;
步骤如下:
步骤 1:生成 256 位 ECC 私钥
bash
# 生成prime256v1(256位)曲线的ECC私钥,保存到ecc256_private.pem
openssl ecparam -genkey -name prime256v1 -out ecc256_private.pem
-
-name prime256v1:强制指定 256 位曲线(这是生成 256 位密钥的核心); -
若需要给私钥加密码保护(防止泄露),添加
-aes256参数,添加密码保护:bash# 用 ec 命令给私钥加密,-aes256 指定加密算法 openssl ec -in ecc256_private_plain.pem -aes256 -out ecc256_private_encrypted.pem执行后会提示你输入并确认密码(比如输入
123456),完成后ecc256_private_encrypted.pem就是带密码保护的加密私钥。添加密码保护之后,如何需要查看原本内容,则需要输入密码:
bash# 查看加密私钥的信息(会提示输入密码) openssl ec -in ecc256_private_encrypted.pem -text -noout输入正确密码后,会显示私钥的曲线信息(
prime256v1)和密钥内容,说明加密成功。
bash
openssl ecparam -genkey -name prime256v1 -aes256 -out ecc256_private_encrypted.pem
步骤 2:从私钥提取 256 位 ECC 公钥
bash
# 从256位私钥提取公钥,保存到ecc256_public.pem
openssl ec -in ecc256_private.pem -pubout -out ecc256_public.pem
步骤 3:验证密钥长度(关键!确认是 256 位)
生成后务必验证,确保不是其他长度:
bash
# 查看私钥信息,确认256位
openssl ec -in ecc256_private.pem -text -noout
# 查看公钥信息,确认256位
openssl ec -in ecc256_public.pem -pubin -text -noout
关键输出特征(证明是 256 位):
bash
Public-Key: (256 bit) # 明确标注256位
ASN1 OID: prime256v1 # 曲线对应256位
2.2 生成摘要
使用 SHA-256 哈希算法生成固定 256 位 数字摘要(也叫哈希值 / 指纹)。
1. 基础用法
bash
# 对目标文件生成 SHA-256 摘要,输出十六进制格式
openssl dgst -sha256 你的文件路径
示例 (对 test_file.txt 生成摘要):
bash
openssl dgst -sha256 test_file.bin
输出示例:
bsh
SHA256(test_file.txt)= 54d541e17ad8cb0f212d62bf7dda783569a3b5ac1a96698b8a6788d4def66dad
- 等号后就是该文件的 SHA-256 摘要(64 个十六进制字符 = 32 字节 = 256 位)。
2. 生成十六进制摘要
如果只需纯摘要字符串(便于复制 / 脚本处理),添加 -binary 直接输出 32 字节的二进制数据 ,再通过 xxd 指令将二进制文件转可读的十六进制文本:
bash
# 仅输出纯 SHA-256 摘要(无多余字符)
openssl dgst -sha256 -binary test_file.txt | xxd -p -c 100
输出示例:输出为64个十六进制字符
bash
54d541e17ad8cb0f212d62bf7dda783569a3b5ac1a96698b8a6788d4def66dad
3. 将摘要保存到文件
bash
# 把 SHA-256 摘要保存到 hash.txt 文件
openssl dgst -sha256 test_file.bin > hash.txt
# 或保存纯摘要(推荐)
openssl dgst -sha256 -binary test_file.bin | xxd -p -c 100 > hash.txt
l为了更紧凑,可以将 SHA-256 二进制摘要转换成 Base64 编码的文本格式,兼顾 "紧凑性" 和 "可读性 / 可传输性",比十六进制更适合文本场景使用可以;
bash
$ openssl dgst -sha256 -binary test_file.bin | base64
通过 | base64 转换后,会得到 44 个字符的 Base64 文本字符串 (末尾可能带 = 补位)
输出示例:
bash
VNVB4XrYyw8hLWK/fdp4NWmjtawalmmLimeI1N72ba0=
Base64 是 "无损编码"------ 编码后的字符串能 100% 转回原始 32 字节二进制摘要,不会丢失任何信息,base64解码后即可得到原始数据。
2.3 使用私钥对摘要进行签名
数字签名过程的是 "用私钥加密哈希摘要",而非加密文件本身 ------ 因为文件可能很大,直接签名效率低,所以一般需要计算出 SHA-256 摘要(32 字节),再用私钥对这个短摘要签名。
签名文件实际上是"文件摘要 + 私钥" 绑定的凭证(r/s)。
1. 先生成摘要,再单独签名(灵活可控)
如果你需要先手动生成 SHA-256 摘要文件,再用私钥对摘要签名(比如摘要需要单独存储 / 传输),步骤如下:
步骤 1:生成文件的 SHA-256 二进制摘要
bash
# 生成纯二进制摘要(无任何编码),保存到 hash_binary.bin
openssl dgst -sha256 -binary test_file.bin > hash_binary.bin
- 这个文件是 32 字节的原始二进制数据,是签名的核心输入。
步骤 2:用私钥对二进制摘要签名
# 对二进制摘要签名,保存签名文件
openssl pkeyutl -sign -inkey ecc256_private.pem -in hash_binary.bin -out signature.bin -pkeyopt digest:sha256
- 参数说明:
-sign:指定签名模式;-inkey ecc256_private.pem:指定 ECC 私钥;-in hash_binary.bin:输入要签名的二进制摘要;-pkeyopt digest:sha256:指定摘要算法为 SHA-256(必须和生成摘要时一致);
- 若私钥加密,同样需要输入密码。
2. OpenSSL 快速生成签名
OpenSSL 可以自动完成「计算 SHA-256 摘要 + 私钥签名」的全过程,无需手动生成摘要文件:
步骤 1:用 ECC 私钥对文件签名
bash
# 核心命令:-sha256 指定哈希算法,-sign 后跟私钥文件,-out 保存签名文件
openssl dgst -sha256 -sign ecc256_private.pem -out signature.bin test_file.bin
-
参数说明:
-sha256:先对test_file.txt计算 SHA-256 摘要;-sign ecc256_private.pem:用你的 256 位 ECC 私钥对摘要签名;-out signature.bin:将二进制签名保存到文件(70~72 字节,符合你之前看到的正常长度);
-
如果私钥是加密的(带密码),执行后会提示输入私钥密码,验证后才会生成签名。
步骤 2:验证签名是否生成成功
bash
# 查看签名文件的基本信息(确认不是空文件)
ls -l signature.bin
# 解析签名结构(确认是合法的 ECDSA 签名)
openssl asn1parse -inform der -in signature.bin
输出会显示签名的 ASN.1 结构(包含 r/s 值),说明签名生成成功。
3. ECC签名文件的内容
ECC签名文件里存的是什么?
使用 xxd 指令查看原始二进制,示例如下:
总共 71 个字节。
bash
$ xxd -C signature.bin
00000000: 3045 0220 592f 1649 fa2f 8d05 d15c 5ef2 0E. Y/.I./...\^.
00000010: 5a78 d40f 5a5e 98e3 3257 2ef6 0c9c 8dad Zx..Z^..2W......
00000020: c01b 34f1 0221 00f8 6183 f192 9852 0bd3 ..4..!..a....R..
00000030: 381a c00a 350e 2a65 d74c c277 28ee 6b5d 8...5.*e.L.w(.k]
00000040: c93c 1c77 2d3a 08 .<.w-:.
使用 OpenSSL asn1parse 解析签名文件的结构如下:
bash
# 解析签名结构(确认是合法的 ECDSA 签名)
$ openssl asn1parse -inform der -in signature.bin
0:d=0 hl=2 l= 69 cons: SEQUENCE
2:d=1 hl=2 l= 32 prim: INTEGER :592F1649FA2F8D05D15C5EF25A78D40F5A5E98E332572EF60C9C8DADC01B34F1
36:d=1 hl=2 l= 33 prim: INTEGER :F86183F19298520BD3381AC00A350E2A65D74CC27728EE6B5DC93C1C772D3A08
输出解读:
d=0:ASN.1 结构层级(0 是根节点,1 是子节点);hl=2:头部长度(2 字节);- l=69:SEQUENCE 总长度 ;
INTEGER后的一串十六进制:就是签名的核心 ------r值(第 2 行)和s值(第 3 行)。
示例中,整个签名文件大小为71字节,其中包含了r/s 两个大整数,r 和 s 不是随机数,而是通过严格的数学规则生成的。这两个值是签名的 "灵魂":验证时,公钥会结合 r/s、原始文件摘要,做数学运算,判断 "这个签名是否由对应私钥生成,且文件未被篡改。
总结: **签名文件本质是 ECDSA 算法生成的两个大整数 r 和 s(构成签名核心),并以 ASN.1/DER 二进制格式封装后的结果 **------ 没有原始文件内容,也没有哈希摘要,只包含 "验证文件合法性" 的核心签名数据。
2.4 验证签名
前面我们知道,签名文件是 "文件摘要 + 私钥" 绑定的凭证(r/s),因此必须结合 " 原始文件 + 公钥 " 才能验证签名是否合法。
使用公钥,和原始文件 验证签名:
bash
# 用公钥验证签名(核心:-verify 后跟公钥,-signature 后跟签名文件)
openssl dgst -sha256 -verify ecc256_public.pem -signature signature.bin test_file.bin
- 输出
Verified OK:签名合法(摘要未篡改、私钥匹配); - 输出
Verification Failure:签名无效(文件篡改、私钥错误或摘要算法不匹配)。
验证时提供原始文件,本质是为了 重新计算文件的 SHA-256 摘要 。
验证时,公钥会结合 r/s、原始文件摘要,做数学运算,判断 "这个签名是否由对应私钥生成,且文件未被篡改。
三、名称解释:
ECC数字签名:
- 签名(如 ECDSA、RSA 签名)本质是 数学验证凭证 ,不是对摘要的 "加密"。
- 公钥的作用是 验证签名的合法性,而不是 "解密" 出原始摘要。
- 从ECC签名文件中无法提取出摘要内容 :整个验证过程中,无法从ECC签名文件中得到任何摘要内容,只能得到 "签名是否合法" 的结论。
ECDSA = Elliptic Curve Digital Signature Algorithm:基于 ECC 椭圆曲线的签名算法。