背景
早期局限性
- 数学工具缺失 :
当时尚未发现双线性对(Bilinear Pairing)在椭圆曲线上的高效实现,而这是构造IBE的关键。 - 安全性证明困难 :
缺乏形式化安全模型(如随机预言模型、标准模型)的支持。
该论文的签名方案使用了类RSA的签名方案,故忽略了RSA签名的具体过程,需要读者自行复习和思考. 为了博客知识的完整性,笔者选择性的保留了大部分论文当中的内容 对RSA加解密过程及其签名过程的了解对你了解本文十分有帮助,若对此感到生疏,建议先学习RSA的相关内容
IBC基本过程
发卡
IBC的实现依赖受信任的密钥生成中心 (Key generation centers ),在每个用户第一次 加入网络时为其提供一张智能卡 (Smart Card)。智能卡中的信息可以让用户完全独立的对收发信息进行签名验签和加密解密。
相较于传统PKI
当有新用户加入网络时, 之前发放的卡无需更新,各个中心也无需协调其活动,甚至无需保存用户列表。在所有卡都发放完毕后,这些中心可以关闭,网络仍能以完全去中心化的方式无限期地运行。
对比维度 | 传统PKI系统 | IBC系统 |
---|---|---|
新用户加入 | 需CA颁发证书,更新CRL或OCSP状态。 | 无需颁发证书,身份即公钥,直接绑定私钥。 |
多中心协作 | 多CA需协调信任链(如交叉认证),维护复杂。 | 单一KGC生成私钥,无需多中心协调。 |
用户列表维护 | 需维护证书目录(如LDAP)和撤销列表(CRL)。 | 无需全局用户列表,验证仅依赖主公钥和用户身份标识。 |
动态管理开销 | 高(频繁更新证书、吊销列表)。 | 低(身份与密钥静态绑定)。 |
特点
该方案基于公钥密码系统,有一个额外的特点: 用户不是生成一对随机的公钥/私钥并公布其中一个, 而是选择自己的身份标识信息。 姓名、 社会安全号码、 街道地址、办公室号码或电话号码的任意组合(视具体情况而定) 都可以使用, 只要能唯一地标识用户且用户日后无法否认, 并且这些信息容易获取即可。
基本构造
当用户首次加入网络时,相应的密钥由密钥生成中心计算得出,并以智能卡的形式发放给用户。该卡包含一个微处理器、一个 I/O 端口、一个随机存取存储器(RAM)、一个只读存储器(ROM) 用于存储密钥,以及用于消息加密/解密和签名生成/验证的程序。
基本过程
- 在A与B的通信过程中,
- 用户 A 想要给用户 B 发送消息时,
- A:
- 他会用智能卡中的私钥对消息进行签名,
- 然后使用 B 的姓名和网络地址对签名结果进行加密,
- 再将自己的姓名和网络地址添加到消息中, 然后将其发送给 B。
- B:
- 当 B 收到消息时, 他会用智能卡中的私钥对其进行解密,
- 然后使用发件人的姓名和网络地址作为验证密钥来验证签名。
- A:
密钥必须由密钥生成中心计算得出,而非由用户自行计算。因为用户用来生成密钥的信息获取容易,而密钥生成中心处于特权地位,因为它知晓某些秘密信息(比如某个大数的因数分解),这使其能够计算出网络中所有用户的私钥。
关键要素
- 该方案的整体安全性取决于以下几点:
- 底层加密函数的安全性。
- 密钥生成中心所存储的特权信息的保密性。
- 中心在向用户发放卡片之前所进行的身份核查的彻底性。
- 用户为防止卡片丢失、 被复制或未经授权使用而采取的预防措施。
详解
这种加密方案有效地将消息与识别信息 i 联系起来, 而卡的所有权则有效地将 i 与实际用户联系起来。
与任何其他发放身份证的机构一样, 中心必须仔细审查发卡申请, 以防止虚假申请, 并且必须妥善保管其"印章" , 以防伪造。 用户可以通过密码系统或记住密钥的一部分来保护自己的卡不被未经授权使用。
私钥、 公钥和基于身份的密码系统之间的差异总结在图 1 中。 在所有这些方案中,消息 <math xmlns="http://www.w3.org/1998/Math/MathML"> m m </math>m 通过密钥 <math xmlns="http://www.w3.org/1998/Math/MathML"> k e k_{e} </math>ke 加密,以密文 <math xmlns="http://www.w3.org/1998/Math/MathML"> c c </math>c 的形式通过公开信道传输,并使用密钥 <math xmlns="http://www.w3.org/1998/Math/MathML"> k d k_{d} </math>kd 进行解密。密钥的选择基于一个真正的随机种子 <math xmlns="http://www.w3.org/1998/Math/MathML"> k k </math>k 。
- 在私钥方案(对称密码)中, <math xmlns="http://www.w3.org/1998/Math/MathML"> k e = k d = k k_{e}=k_{d}=k </math>ke=kd=k ,单独的密钥信道(通常是信使) 必须同时保证密钥的保密性和真实性。
- 在公钥方案中,加密密钥和解密密钥通过两个不同的函数从 <math xmlns="http://www.w3.org/1998/Math/MathML"> k k </math>k 衍生而来,即 <math xmlns="http://www.w3.org/1998/Math/MathML"> k e = f e ( k ) ; k d = f d ( k ) k_{e}=f_{e}(k);k_{d}=f_{d}(k) </math>ke=fe(k);kd=fd(k) ,单独的密钥信道(通常是目录) 只需保证密钥的真实性即可。
- 在基于身份的方案中, 加密密钥是用户的标识 <math xmlns="http://www.w3.org/1998/Math/MathML"> k e = i k_e = i </math>ke=i, 而解密密钥则通过 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i 和 <math xmlns="http://www.w3.org/1998/Math/MathML"> k k </math>k 衍生而来, 即 <math xmlns="http://www.w3.org/1998/Math/MathML"> k d = f ( i , k ) k_{d}=f(i,k) </math>kd=f(i,k) 。 用户之间的单独密钥信道被完全消除 ,取而代之的是当接收方首次加入网络时与密钥生成中心的首次交互。
公钥和基于身份的签名方案是相应密码系统的镜像, 如图 2 所示。 消息 <math xmlns="http://www.w3.org/1998/Math/MathML"> m m </math>m 用签名生成密钥 <math xmlns="http://www.w3.org/1998/Math/MathML"> k g k_g </math>kg 进行签名, 连同其签名 <math xmlns="http://www.w3.org/1998/Math/MathML"> s s </math>s 和发送方身份 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i 一起传输, 并用签名验证密钥 <math xmlns="http://www.w3.org/1998/Math/MathML"> k v k_v </math>kv 进行验证。 图中的其余部分应不言自明。

实施
- 首先我们需要准备一个公钥密码方案,这个方案需要具备两个额外的特性:
- 当种子 <math xmlns="http://www.w3.org/1998/Math/MathML"> k k </math>k 已知时, 可以轻松计算出相当一部分可能的公钥所对应的私钥。------用户端的高效性
- 从用此 <math xmlns="http://www.w3.org/1998/Math/MathML"> k k </math>k 生成的特定公钥/私钥对计算种子 <math xmlns="http://www.w3.org/1998/Math/MathML"> k k </math>k 的问题难以解决。------密码分析的困难性
- 不幸的是,RSA 方案无法同时满足以下条件: (详见{课程仓库 - 公钥密码##RSA加密算法 }或 公钥密码-Blog
- 如果模数 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n 是用户身份的伪随机函数, 那么即使密钥生成中心也无法对 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n 进行因式分解, 也无法从加密指数 <math xmlns="http://www.w3.org/1998/Math/MathML"> e e </math>e 计算出解密指数 <math xmlns="http://www.w3.org/1998/Math/MathML"> d d </math>d 。
- 如果模数 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n 是通用的, 而种子是其秘密因式分解, 那么任何知道加密指数 <math xmlns="http://www.w3.org/1998/Math/MathML"> e e </math>e 及其对应的解密指数 <math xmlns="http://www.w3.org/1998/Math/MathML"> d d </math>d 的人都能计算出种子。
该签名方案基于验证条件:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> s e = i ⋅ t f ( t , m ) m o d n s^{e}=i \cdot t^{f(t,m)}\mod{n} </math>se=i⋅tf(t,m)modn
- 定义:
- <math xmlns="http://www.w3.org/1998/Math/MathML"> m m </math>m 是消息
- <math xmlns="http://www.w3.org/1998/Math/MathML"> s , t s,t </math>s,t 是签名
- <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i 是用户的标识
- <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n 是两个大质数的乘积
- <math xmlns="http://www.w3.org/1998/Math/MathML"> e e </math>e 是一个大素数, 且与 <math xmlns="http://www.w3.org/1998/Math/MathML"> φ ( n ) φ(n) </math>φ(n) 互质。
- <math xmlns="http://www.w3.org/1998/Math/MathML"> f f </math>f 是一个单向函数。
参数 <math xmlns="http://www.w3.org/1998/Math/MathML"> n , e n,e </math>n,e 以及函数 <math xmlns="http://www.w3.org/1998/Math/MathML"> f f </math>f 由密钥生成中心选定 , 所有用户都将其相同的 <math xmlns="http://www.w3.org/1998/Math/MathML"> n , e n,e </math>n,e 以及 <math xmlns="http://www.w3.org/1998/Math/MathML"> f f </math>f 的算法描述存储在各自的智能卡中。 这些值可以公开, 但 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n 的因数分解情况仅应由密钥生成中心知晓。 用户之间的唯一区别 在于 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i 的值, 而与 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i 相对应的私钥是唯一的数 <math xmlns="http://www.w3.org/1998/Math/MathML"> g g </math>g,满足以下条件:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> g e = i m o d n g^{e}=i\mod{n} </math>ge=imodn
这个 <math xmlns="http://www.w3.org/1998/Math/MathML"> g g </math>g 可以由密钥生成中心轻松计算得出, 但如果 RSA 方案是安全的, 那么其他人就无法在模 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n下求出 <math xmlns="http://www.w3.org/1998/Math/MathML"> e e </math>e 次方根。
每条消息 <math xmlns="http://www.w3.org/1998/Math/MathML"> m m </math>m 都有大量可能的 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( s , t ) (s,t) </math>(s,t) 签名, 但其密度极低, 以至于随机搜索几乎不可能发现其中任何一个。任何试图将 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( s , t ) (s,t) </math>(s,t) 中的一个设为随机值并求解另一个变量的做法都需要提取模根, 这被认为是一项极其困难的计算任务。 然而, 当 <math xmlns="http://www.w3.org/1998/Math/MathML"> g g </math>g 已知时, 即使 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n 的因数分解未知, 也有非常简单的方法可以为任何消息生成任意数量的签名。
要对消息 <math xmlns="http://www.w3.org/1998/Math/MathML"> m m </math>m 进行签名, 用户需选择一个随机数 <math xmlns="http://www.w3.org/1998/Math/MathML"> r r </math>r 并计算:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> t = r e m o d n t=r^{e}\mod{n} </math>t=remodn
验证条件可以重写为
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> s e = g e ⋅ r e f ( t , m ) m o d n s^{e}=g^{e}\cdot r^{ef(t,m)}\mod{n} </math>se=ge⋅ref(t,m)modn
由于 <math xmlns="http://www.w3.org/1998/Math/MathML"> e e </math>e 与 <math xmlns="http://www.w3.org/1998/Math/MathML"> φ ( n ) \varphi(n) </math>φ(n) 互质, 我们可以从指数中消去公因数 <math xmlns="http://www.w3.org/1998/Math/MathML"> e e </math>e 有
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> s = g ⋅ r f ( t , m ) m o d n s=g\cdot r^{f(t,m)}\mod{n} </math>s=g⋅rf(t,m)modn
因此, <math xmlns="http://www.w3.org/1998/Math/MathML"> s s </math>s 可以在不进行任何开方运算的情况下计算出来。
-
!\] 论文默认读者熟悉RSA签名过程,故笔者在此作补充。
系统的初始化 密钥中心(PKG)执行
由私钥中心(PKG)生成系统公私钥参数。
系统参数(类似 RSA):
- 选择两个大素数 <math xmlns="http://www.w3.org/1998/Math/MathML"> p , q p, q </math>p,q
- 计算 <math xmlns="http://www.w3.org/1998/Math/MathML"> n = p ⋅ q n = p \cdot q </math>n=p⋅q
- 选择一个与 <math xmlns="http://www.w3.org/1998/Math/MathML"> ϕ ( n ) \phi(n) </math>ϕ(n) 互素的整数 <math xmlns="http://www.w3.org/1998/Math/MathML"> e e </math>e,如 <math xmlns="http://www.w3.org/1998/Math/MathML"> e = 3 , 17 , 65537 e = 3, 17, 65537 </math>e=3,17,65537
- 计算 <math xmlns="http://www.w3.org/1998/Math/MathML"> d = e − 1 m o d ϕ ( n ) d = e^{-1} \mod \phi(n) </math>d=e−1modϕ(n),这是系统私钥
最终系统公钥: <math xmlns="http://www.w3.org/1998/Math/MathML"> ( n , e ) (n, e) </math>(n,e),系统私钥: <math xmlns="http://www.w3.org/1998/Math/MathML"> d d </math>d
密钥生成
任何用户只需提供其身份标识符 ID
,即可获得由 PKG 派发的私钥。
步骤:
- 用户名和身份 ID(如
author_name="seveN1foR"
,author_ID=424
)经某种可逆编码 映射为整数 <math xmlns="http://www.w3.org/1998/Math/MathML"> u ∈ Z n ∗ u\in \mathbb{Z}^{*}_{n} </math>u∈Zn∗ - PKG 计算该用户的私钥 <math xmlns="http://www.w3.org/1998/Math/MathML"> g g </math>g 为: <math xmlns="http://www.w3.org/1998/Math/MathML"> g = u d m o d n g = u^d \mod n </math>g=udmodn
- 用户身份信息 <math xmlns="http://www.w3.org/1998/Math/MathML"> i = g e m o d n i=g^{e}\mod{n} </math>i=gemodn
这个 <math xmlns="http://www.w3.org/1998/Math/MathML"> g g </math>g 就是用户的身份私钥 ,PKG 通过主私钥 <math xmlns="http://www.w3.org/1998/Math/MathML"> d d </math>d 计算出来。
签名
签名过程由用户使用其身份私钥 <math xmlns="http://www.w3.org/1998/Math/MathML"> g g </math>g 来对一条消息 <math xmlns="http://www.w3.org/1998/Math/MathML"> m m </math>m 进行签名。
步骤如下:
-
用户想签名消息
m
:- 随机选择一个数 <math xmlns="http://www.w3.org/1998/Math/MathML"> r ∈ Z n ∗ r ∈ Z_n^* </math>r∈Zn∗
- 计算 <math xmlns="http://www.w3.org/1998/Math/MathML"> t = r e m o d n t = r^e \mod n </math>t=remodn
- 使用自己的私钥
g
,计算签名值: <math xmlns="http://www.w3.org/1998/Math/MathML"> s = g ⋅ r f ( t , m ) m o d n s = g \cdot r^{f(t, m)} \mod n </math>s=g⋅rf(t,m)modn
-
!\] 注意:在 Shamir 方案中, s 本身可以是签名的一部分输出(用于验证者获取),但也可以是通过 ID 推导的隐含变量
验证步骤:
- 接收方(验证者)已知:
- 来自PKG: <math xmlns="http://www.w3.org/1998/Math/MathML"> ( n , e ) , f ; {\color{red} (n,e),f;} </math>(n,e),f;
- 来自发送端: <math xmlns="http://www.w3.org/1998/Math/MathML"> i , m , ( s , t ) {\color{red} i,m,(s,t) } </math>i,m,(s,t)
- 公共参数------系统公钥 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( n , e ) (n,e) </math>(n,e)和单向函数 <math xmlns="http://www.w3.org/1998/Math/MathML"> f f </math>f
- 用户身份信息 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i
- 消息 <math xmlns="http://www.w3.org/1998/Math/MathML"> m m </math>m------论文并没有提出能够满足IBC条件的加解密算法,所以这里默认接收方已解密得到消息 <math xmlns="http://www.w3.org/1998/Math/MathML"> m m </math>m
- 签名对 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( s , t ) (s,t) </math>(s,t)
- 验证:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> s e = ? i ⋅ t f ( t , m ) m o d n s^{e} \stackrel{?}{=}i\cdot t^{f(t,m)}\mod{n} </math>se=?i⋅tf(t,m)modn
- For your convenience :
- <math xmlns="http://www.w3.org/1998/Math/MathML"> i = g e m o d n i=g^{e}\mod{n} </math>i=gemodn
- <math xmlns="http://www.w3.org/1998/Math/MathML"> t = r e m o d n t=r^{e}\mod{n} </math>t=remodn
- <math xmlns="http://www.w3.org/1998/Math/MathML"> s = g ⋅ r f ( t , m ) s=g\cdot r^{f(t,m)} </math>s=g⋅rf(t,m)
- 代入有
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> s e = ( g ⋅ r f ( t , m ) ) e = g e ⋅ r e ⋅ f ( t , m ) = i ⋅ t f ( t , m ) \begin{array}{l} s^{e} & =(g\cdot r^{f(t,m)})^{e} \\ & =g^{e}\cdot r^{e\cdot f(t,m)} \\ & = i\cdot t^{f(t,m)} \end{array} </math>se=(g⋅rf(t,m))e=ge⋅re⋅f(t,m)=i⋅tf(t,m)
补充
为防止基于不同用户身份(以及相应的 <math xmlns="http://www.w3.org/1998/Math/MathML"> g g </math>g 值) 之间乘法关系的攻击, 建议通过通用单向函数将描述用户身份的字符串扩展为一个长的伪随机字符串, 并将扩展后的形式用作验证条件中的 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i 。 由于网络中的每个人都知晓如何应用此函数, 因此尽管签名验证密钥并非严格等于用户身份, 但该方案仍保留了基于身份的特性。
安全性
该方案的安全性取决于密码分析者无法通过分析大量由其选择的消息的有效签名来分离出 <math xmlns="http://www.w3.org/1998/Math/MathML"> g g </math>g 。 如果 <math xmlns="http://www.w3.org/1998/Math/MathML"> g c d ( f , e ) gcd(f,e) </math>gcd(f,e) 为 <math xmlns="http://www.w3.org/1998/Math/MathML"> c ≠ 1 c \neq 1 </math>c=1 , 则可以通过操作验证条件来提取 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i 的 <math xmlns="http://www.w3.org/1998/Math/MathML"> c c </math>c 次方根, 因此必须使 <math xmlns="http://www.w3.org/1998/Math/MathML"> e e </math>e 足够大且为素数, 同时使 <math xmlns="http://www.w3.org/1998/Math/MathML"> f f </math>f 足够强的单向函数, 以确保这种情况在实际中永远不会发生。 <math xmlns="http://www.w3.org/1998/Math/MathML"> r r </math>r 的值绝不能重复使用或泄露, 因为在任何具体的签名中, <math xmlns="http://www.w3.org/1998/Math/MathML"> g g </math>g 都受到其随机性和保密性的保护。
在验证条件的变体中, 如果消除了两个 <math xmlns="http://www.w3.org/1998/Math/MathML"> t t </math>t 中的一个(例如, 将其替换为常量),则这些变体是不安全的。 因此,重要的是要使用一种单向函数, 该函数能将 <math xmlns="http://www.w3.org/1998/Math/MathML"> t t </math>t 和 <math xmlns="http://www.w3.org/1998/Math/MathML"> m m </math>m 彻底混合(最好通过非算术和不可逆的操作), 并且具有很大的可能值范围。
随机承诺值 r
这个问题问得非常关键。我们来逐层解析 r
和 t
的作用,它们不仅仅是"技术性细节",而是这个签名方案安全性 和可验证性的核心设计。
🔁 回顾一下定义
- <math xmlns="http://www.w3.org/1998/Math/MathML"> r r </math>r:签名者 私下选取 的随机数
- <math xmlns="http://www.w3.org/1998/Math/MathML"> t = r e m o d n t = r^e mod n </math>t=remodn:公开出来的,签名的一部分(可用于验证)
- <math xmlns="http://www.w3.org/1998/Math/MathML"> s = g ⋅ r f ( t , m ) m o d n s = g · r^{f(t, m)} \mod n </math>s=g⋅rf(t,m)modn:签名者计算出的签名值(另一部分)
签名最终是对外提供 (s, t)
。
🧩 r
的作用 ------ 引入随机性,防止重放攻击
如果签名只基于消息 m
和身份 i
,那么同一条消息每次签名都得到一样的结果,会存在很多安全隐患:
- 💀 重放攻击:别人只需记录下你的签名,下次你再次签名相同消息,他也能冒充你。
- 🧮 离线伪造:攻击者可以提前构建一个"签名数据库",提高攻击成功率。
➤ 引入
r
让每次签名都不一样,即使消息m
相同!
🔐 t
的作用 ------ 是验证所需的桥梁值(辅助信息)
t = r^e mod n
是将随机性 r
映射到"验证空间"中。
签名者使用 r
计算 t
,然后把 t
作为输入提供给函数 f(t, m)
来加入消息依赖。验证者不知道 r
,但他知道 t
,可以计算:
<math xmlns="http://www.w3.org/1998/Math/MathML"> s e = ? i ⋅ t f ( t , m ) m o d n s^e \overset{?}{=} i \cdot t^{f(t,m)} \mod n </math>se=?i⋅tf(t,m)modn
所以 t
是:
- ⚙️ 将签名者使用的随机性 暴露成验证者可使用的值
- 🧩 确保签名验证方能"恢复"出验证路径 ,不需要知道
r
本身
🔁 总结一下
项目 | 角色 | 作用 |
---|---|---|
r |
私密 | 引入随机性,防止签名被复用 |
t |
公开 | 验证时的桥梁,让验证方可以重现随机性影响但不泄露随机性本身 |
s |
签名值 | 将用户身份、随机性和消息耦合的结果 |
✅ 为啥不能只用 t
?
因为 t = r^e mod n
是公开的,如果签名只用 t
,别人可以伪造。只有你知道 r
才能计算出真正的 s = g * r^{f(t, m)} mod n
。
如果你熟悉 Schnorr 或 ECDSA 签名,会发现它们也有一个类似的 (r, s)
或 (R, s)
结构,这是一种非常经典的设计理念:签名 = 随机承诺值 + 信息绑定函数输出。
展望
- 限于笔者水平有限,也就只能写到RSA模式下的IBC签名,但这已经足够读者熟悉IBC的基本过程了。
SM9可能需要如何密评?
-
其实和传统的PKI没有太大的差别
- 密码设备的算法截图:同其他签名算法一样,需要服务器密码机或者签名验签服务器对证书进行加解密。
- 密码设备的登录 (身份鉴别):设备层面的密码设备身份鉴别是我们再熟悉不过的了,一般使用Ukey进行
- 对于DAK的判定就来到了我们熟悉的国密、产品证书等了。