J. Bethencourt, A. Sahai and B. Waters, “Ciphertext-Policy Attribute-Based Encryption,” 2007 IEEE Symposium on Security and Privacy (SP '07), 2007, pp. 321-334, doi: 10.1109/SP.2007.11.
python的charm-crypto库,abenc_bsw07源码阅读
CP-ABE方案首次由 J. Bethencourt,A. Sahai 和 B. Waters在 IEEE Symposium on Security and Privacy (SP '07)上发布,该方案也常被成为BSW(三人名字首字母)。该方案改善了Sahai等人在2005年发表的基于身份的模糊加密方案 (FIBE),该方案将用户身份分解成一系列描述用户身份的属性,加密者加密数据时指定一个属性集合和阈值d ,解密者必须拥有至少d个给定的属性才能正确解密密文。FIBE方案是BSW方案的雏形。因为BSW方案是对FIBE方案的改进,在算法设计中也使用了FIBE方案的思想和运算原理,在其基础上添加了访问控制树,以及递归求解访问控制树 。
1.方案定义
该方案由5个基本算法组成:Setup、Encrypt、KeyGen、Decrypt和 Delegate。
S e t u p \mathrm{Setup} Setup :该算法以隐含安全参数λ作为输入,输出系统公钥PK和主私钥MK。
E n c r y p t ( P K , M , A ) → C T \mathrm{Encrypt}(PK, M, A) → CT Encrypt ( P K , M , A ) → CT :该算法输入系统公钥PK、明文M和基于属性的访问结构A,输出对明文M加密后密文CT,且只有用户拥有的属性集合满足访问结构A才能正确解密密文CT。
K e y G e n ( M K , P K , S ) → S K \mathrm{KeyGen}(MK, PK, S)→ SK KeyGen ( M K , P K , S ) → S K :该算法以系统主私钥MK和属性集合S作为输入,输出用户私钥SK。
D e c r y p t ( P K , C T , S K ) → M \mathrm{Decrypt}(PK, CT, SK) → M Decrypt ( P K , CT , S K ) → M :该算法输入系统公钥PK、密文CT和用户私钥SK作为输入,若S满足A,则能够正确解密密文并输出明文M。
D e l e g a t e ( S K , S ~ ) → S K ~ \mathrm{Delegate}(SK,\tilde{S})\to \tilde{SK} Delegate ( S K , S ~ ) → S K ~ :该算法输入属性集合S S S 的私钥S K SK S K 和一个属性集合S ~ \tilde{S} S ~ 且S ~ ⊆ S \tilde{S}\subseteq S S ~ ⊆ S ,输出一个基于属性集合S ~ \tilde{S} S ~ 的私钥S K ~ \tilde{SK} S K ~ 。
2.算法详细设计
该方案用到以下基本条件:
令G 0 G_0 G 0 为一个阶为素数p p p 的双线性群,g g g 为G 0 G_0 G 0 的生成元。
令e : G 0 × G 0 → G 1 e:G_0\times G_0\to G_1 e : G 0 × G 0 → G 1 表示双线性映射。
群的大小由安全参数λ \lambda λ 决定
对于i ∈ Z p i\in Z_{p} i ∈ Z p 和Z p Z_p Z p 中元素组成的集合S S S ,定义拉格朗日系数Δ i , S ( x ) = ∏ j ∈ S , j ≠ i x − j i − j \Delta_{i,S}(x)=\prod_{j\in S,j\neq i}\frac{x-j}{i-j} Δ i , S ( x ) = ∏ j ∈ S , j = i i − j x − j 。
应用一个哈希函数H : { 0 , 1 } ∗ → G 0 H:\{0,1\}^*\to G_0 H : { 0 , 1 } ∗ → G 0 ,该函数能将任意字符串描述的属性映射为一个随机的群元素
2.1 Setup
该算法以隐含安全参数λ \lambda λ 作为输入,输出系统公钥PK和主私钥MK。
该算法选择一个阶为p p p 的双线性群G 0 G_0 G 0 ,该群的生成元为g g g 。然后随机选择加密指数α , β ∈ Z P \alpha,\beta \in Z_P α , β ∈ Z P 。输出系统公钥P K = ( G 0 , g , h = g β , f = g 1 β , e ( g , g ) α ) PK=(G_0,g,h=g^\beta,f=g^{\frac1\beta},e(g,g)^\alpha) P K = ( G 0 , g , h = g β , f = g β 1 , e ( g , g ) α ) ;系统主密钥M K = ( β , g α ) MK=(\beta,g^\alpha) M K = ( β , g α ) 。
2.2 KeyGen
K e y G e n ( M K , P K , S ) → S K \mathrm{KeyGen}(MK, PK, S)→ SK KeyGen ( M K , P K , S ) → S K :该算法以系统主私钥M K MK M K 和属性集合S S S 作为输入,输出用户私钥S K SK S K 。
首先随机选择一个随机数r ∈ Z p r\in Z_{p} r ∈ Z p ,然后对于每个属性j ∈ S j\in S j ∈ S ,随机选择r j ∈ Z p r_j\in Z_p r j ∈ Z p 。这个过程是属性集合S S S 中有几个属性,那就再Z p Z_p Z p 里面随机找几个数r j r_j r j ,然后再按照如下过程计算用户私钥:
S K = ( D = g α + r β , ∀ j ∈ S : D j = g r ⋅ H ( j ) r j , D j ′ = g r j ) SK=(D=g^{\frac{\alpha+r}\beta},\forall j\in S:D_j=g^r\cdot H(j)^{r_j},D_j^{^{\prime}}=g^{r_j})
S K = ( D = g β α + r , ∀ j ∈ S : D j = g r ⋅ H ( j ) r j , D j ′ = g r j )
利用P K PK P K 和M K MK M K 里的相关参数和属性集S S S 来计算私钥。
∀ j ∈ S : D j = g r ⋅ H ( j ) r j , D j ′ = g r j \forall j\in S:D_j=g^r\cdot H(j)^{r_j},D_j^{'}=g^{r_j} ∀ j ∈ S : D j = g r ⋅ H ( j ) r j , D j ′ = g r j ,则表示属性集S S S 里含有几个属性,我们就从Z p Z_p Z p 里选出几个随机数来计算相应的D j D_j D j 和D j ′ D_j^{^{\prime}} D j ′ 。
2.3 Encrypt
E n c r y p t ( P K , M , A ) → C T \mathrm{Encrypt}(PK, M, A) → CT Encrypt ( P K , M , A ) → CT :该算法输入系统公钥P K PK P K 、明文M M M 和基于属性的访问结构A A A ,输出对明文M M M 加密后密文C T CT CT ,且只有用户拥有的属性集合满足访问结构A A A 才能正确解密密文C T CT CT 。
首先对访问结构A A A 中的访问控制树T T T 中的每个节点x x x (包括叶子节点)选择一个多项式q x q_x q x ,这些多项式自上而下从根节点R R R 进行选择。对于树中的每一个节点x x x ,设多项式q x q_x q x 的阶d x d_x d x 为节点x x x 的阈值k x k_x k x 减去1,即d x = k x − 1 d_x=k_x-1 d x = k x − 1 。
从根节点R R R 开始随机选择s ∈ Z p s\in Z_{p} s ∈ Z p 并设置q R ( 0 ) = s q_R(0)=s q R ( 0 ) = s 。然后随机选择多项式q R q_R q R 的其他d R d_R d R 个点来定义该多项式。对于任何其他节点x x x ,令q x ( 0 ) = q p a r e n t ( x ) ( i n d e x ( x ) ) q_x(0)=q_{parent(x)}(index(x)) q x ( 0 ) = q p a re n t ( x ) ( in d e x ( x )) 且随机选择多项式q x q_x q x 的其他d x d_x d x 个点来定义该多项式。
有点费解,那就举个例子吧!
由图可知,属性值都在叶子节点上,而非叶子节点都是满足条件个数的门限。除了叶子节点,所有非叶子节点都是a / b a/b a / b 的形式,表示改节点有b b b 个子节点,要满足其中a a a 个子节点才可以。而非叶子节点才会有随机生成的多项式q x q_x q x ,多项式q x q_x q x 的阶就是该多项式的最高次幂,至于这个阈值k x k_x k x 就是a / b a/b a / b 这个形式的a a a 。
接下来,对这一层的非叶子节点再按照根节点的多项式生成规则,为其随机生成多项式。
令Y Y Y 为访问控制树T T T 的所有叶子节点的集合,那么通过控制结构构造的密文为
C T = ( T , C ~ = M e ( g , g ) α s , C = h s , ∀ y ∈ Y : C y = g q y ( 0 ) , C y ′ = H ( a t t ( y ) ) q y ( 0 ) ) CT=(T,\tilde{C}=Me(g,g)^{\alpha s},C=h^s,\forall y\in Y:C_y=g^{q_y(0)},C_y^{\prime}=H(att(y))^{q_y(0)})
CT = ( T , C ~ = M e ( g , g ) α s , C = h s , ∀ y ∈ Y : C y = g q y ( 0 ) , C y ′ = H ( a tt ( y ) ) q y ( 0 ) )
T T T 表示访问控制树。
C ~ = M e ( g , g ) α s \tilde{C}=Me(g,g)^{\alpha s} C ~ = M e ( g , g ) α s 。M M M 表示明文,s s s 就是根节点上要隐藏的秘密值(上面例子中的5),这个值是在Z p Z_p Z p 中随机选取的。
C = h s C=h^s C = h s ,直观理解即可。
∀ y ∈ Y : C y = g q y ( 0 ) , C y ′ = H ( a t t ( y ) ) q y ( 0 ) \forall y\in Y:C_y=g^{q_y(0)},C_y^{\prime}=H(att(y))^{q_y(0)} ∀ y ∈ Y : C y = g q y ( 0 ) , C y ′ = H ( a tt ( y ) ) q y ( 0 ) ,这是对叶子节点的操作,每个叶子节点经过这样计算,都会有一个值,比如上面例子中“网信院”对应值就是19。
2.4 Decrypt
D e c r y p t ( P K , C T , S K ) → M \mathrm{Decrypt}(PK, CT, SK) → M Decrypt ( P K , CT , S K ) → M :该算法输入系统公钥PK、密文CT和用户私钥SK作为输入,若S满足A,则能够正确解密密文并输出明文M。
解密过程是一个递归算法D e c r y p t N o d e ( C T , S K , x ) \mathrm{DecryptNode}(CT,SK,x) DecryptNode ( CT , S K , x ) 。该算法输入为一个密文,C T = ( T , C ~ , C , ∀ y ∈ Y : C y , C y ′ ) CT=(T,\tilde{C},C,\forall y\in Y:C_y,C_y^{^{\prime}}) CT = ( T , C ~ , C , ∀ y ∈ Y : C y , C y ′ ) ,一个属性集S S S 的私钥S K SK S K 和树T T T 中的一个节点x x x 。
假如x x x 是一个叶子节点,令i = a t t ( x ) i=att(x) i = a tt ( x ) ,假如i ∈ S i\in S i ∈ S ,定义:
D e c r y p t N o d e ( C T , S K , x ) = e ( D i , C x ) e ( D i ′ , C x ′ ) = e ( g r ⋅ H ( i ) r i , h q x ( 0 ) ) e ( g r i , H ( i ) q x ( 0 ) ) = e ( g , g ) r ⋅ q x ( 0 ) \mathrm{DecryptNode}(CT,SK,x)=\frac{e(D_i,C_x)}{e(D_i^{'},C_x^{'})}=\frac{e(g^r\cdot H(i)^{r_i},h^{q_x(0)})}{e(g^{r_i},H(i)^{q_x(0)})}=e(g,g)^{r\cdot q_x(0)}
DecryptNode ( CT , S K , x ) = e ( D i ′ , C x ′ ) e ( D i , C x ) = e ( g r i , H ( i ) q x ( 0 ) ) e ( g r ⋅ H ( i ) r i , h q x ( 0 ) ) = e ( g , g ) r ⋅ q x ( 0 )
这个过程需要用到双线性映射的性质。
如果i ∉ S i\notin S i ∈ / S 的话,那么这个算法就输出⊥,表示控制结构中的属性不在个人私钥对应的属性集合中,则访问控制结构不满足私钥属性集合,则不能解密。
现在考虑非叶子节点时的递归情况,当x x x 是非叶子节点时,算法的计算情况如下:对于节点x x x 的所有孩子节点z z z ,调用函数D e c r y p t N o d e ( C T , S K , z ) \mathrm{DecryptNode}(CT,SK,z) DecryptNode ( CT , S K , z ) 并存储其结果为F z F_z F z 。令S x S_x S x 为一个任意的大小为k x k_x k x 的孩子节点z z z 的集合,并且满足$F_{z}\neq\bot $。如果不存在这样的集合,函数就返回⊥。否则,我们就计算:
F x = ∏ z ∈ S x F z A i , S x ( 0 ) = ∏ z ∈ S x ( e ( g , g ) r ⋅ q p a r e n t ( z ) ( i n d e x ( z ) ) ) A i , S x ′ ( 0 ) = ∏ z ∈ S x e ( g , g ) r ⋅ q x ( i ) ⋅ A i , S x ′ ( 0 ) = e ( g , g ) r ⋅ q x ( 0 ) \begin{aligned}F_x&=\prod_{z\in S_x}F_z^{A_{i,S_x}(0)}=\prod_{z\in S_x}\left(e(g,g)^{r\cdot q_{parent(z)}(index(z))}\right)^{A_{i,S_x^{\prime}}(0)}\\&=\prod_{z\in S_x}e(g,g)^{r\cdot q_x(i)\cdot A_{i,S_x^{\prime}}(0)}=e(g,g)^{r\cdot q_x(0)}\end{aligned}
F x = z ∈ S x ∏ F z A i , S x ( 0 ) = z ∈ S x ∏ ( e ( g , g ) r ⋅ q p a re n t ( z ) ( in d e x ( z )) ) A i , S x ′ ( 0 ) = z ∈ S x ∏ e ( g , g ) r ⋅ q x ( i ) ⋅ A i , S x ′ ( 0 ) = e ( g , g ) r ⋅ q x ( 0 )
其中,i = i n d e x ( z ) i=index(z) i = in d e x ( z ) ,S x ′ = { i n d e x ( z ) : z ∈ S x } S_x^{^{\prime}}=\{index(z):z\in S_x\} S x ′ = { in d e x ( z ) : z ∈ S x }
结合上面的例子,我们现在有"计算机学院"(1,19)、“硕士”(2,44)和"研一"(3,83),所以,根据拉格朗日插值法,我们可以算出这三个节点的父节点的多项式是q x ( x ) = 8 + 4 x + 7 x 2 q_x(x)=8+4x+7x^2 q x ( x ) = 8 + 4 x + 7 x 2 ,这么我们就知道了这个父节点的隐藏秘密值是8。假设现在,我们也知道"教师"(2,11),结合刚解开的那个秘密值是(1,8),两者结合,再拉格朗日插值法一下,就得到了根节点的多项式是q R ( x ) = 5 + 3 x q_R(x)=5+3x q R ( x ) = 5 + 3 x 。这样,我们就得到根节点的秘密值是5。这里,容易会有一个疑问——我在3/3那个节点解出了它的秘密值是8,进行拉格朗日插值计算的时候,我怎么知道它在根节点的index是1,别忘了,密文里面是有完整的访问控制树的结构的,我们可以根据这个结构很容易就能看出来它的index=1 。所以,在参与拉格朗日插值计算时候,就可以自动加入相应的index值计算。