密钥策略的属性基加密(KP-ABE)

目录

KP-ABE的基本知识

KP-ABE过程

KP-ABE的说明

参考文献


KP-ABE的基本知识

基本的属性基加密将密文和密钥都与一组属性关联起来,当密文与密钥之间至少有d个属性重合时,用户就可以解密密文。虽然这个策略对于生物识别的容错加密有一定的作用,但访问控制缺乏灵活性限制了它的应用。密钥策略属性基加密(KP-ABE)的出现弥补了这一缺陷,在KP-ABE系统中,密文与一组描述性属性相关联,用户的私钥与一个访问结构相关联,当密文中的属性集满足用户私钥中的访问策略时,密文才能够被解密。这使得属性基加密能够细粒度共享加密数据,KP-ABE的构造适用于审计日志信息和广播加密。

        在KP-ABE中,与用户私钥相关联的访问结构被构造为访问树。其中树的内部节点都是一个阈值门,由其子节点和阈值描述。如果num_{x}是其子节点的个数,k_{x}是其阈值,则0<k_{x}\leq num_{x}。与门和或门都可以被构造成阈值门,当k_{x}=1时,就是或门,当k_{x}=num_{x}时就是与门。叶子节点与属性相关联,由属性值和阈值k_{x}=1描述。为了便于使用访问数,还定义了一些函数。parent(x)表示树中节点的父节点。att(x)表示与树中叶节点相关联的属性,只有x节点是叶节点时才定义该函数。对于节点的子节点来说,需要对子节点进行编号,index(x)返回子节点的索引值。

        用T_{x}表示以节点x为根的树,则根为r的访问树表示为T_{r},当节点被满足时令T_{x}=1,我们递归计算所有节点,当根节点满足时,我们就可以进行解密操作。否则解密失败。

KP-ABE过程

G1是素数阶p的双线性群,g是G1的生成元。此外e:gif.latex?G1%5Ctimes%20G1%5Crightarrow%20G2表示双线性映射。安全参数k将确定群的大小。同时为gif.latex?i%5Cin%20Zpgif.latex?Zp中元素的集合gif.latex?s定义拉格朗日系数gif.latex?%5CDelta%20_%7Bi%2Cs%7D:

                                                       gif.latex?%5CDelta%20_%7Bi%2Cs%7D%28x%29%3D%5Cprod_%7Bj%5Cin%20s%2Cj%5Cneq%20i%7D%5E%7B%7D%5Cfrac%7Bx-j%7D%7Bi-j%7D.

我们将每个属性与Z_{p}^{*}中的一个唯一的元素关联起来,构造如下:

Setup:定义一个属性域U={1,2,……,n}。对于每个属性i\in U,在Zp中随机选取t_{i},最后,从Zp中随机选取y。

公布公共参数PK为:gif.latex?T_%7B1%7D%3Dg%5E%7Bt_%7B1%7D%7D%2C...%2CT_%7B%7Cu%7C%7D%3Dg%5E%7Bt_%7B%7Cu%7C%7D%7D%2CY%3De%28g%2Cg%29%5E%7By%7D

主密钥MK为:gif.latex?t_%7B1%7D%2C...t_%7B%7Cu%7C%7D%2Cy

Encryption(M,\gamma,PK):在一组属性集合\gamma下加密消息M\inG2,选择一个随机值s\inZ_{p},公布密文如下:

                                  E=(\gamma ,E{}'=MY^{s},\left \{ E_{i} =T_{i}^{s}\right \}_{i\in \gamma })

Key Generation(\tau,MK):这个算法输出一个密钥能够使用户与解密在一组属性\gamma下加密的信息,当且仅当\tau (\gamma )=1。算法过程如下:首先为树中的每个节点x选择一个多项式q_{x}(包括叶子节点),这些多项式从根节点r开始以一种自顶向下的方式选择。

        对于树中的每个节点x,设置多项式q_{x}的次数比节点阈值少一,也就是d_{x}=k_{x}-1。首先,对于根节点r,设置q_{r}(0)=y,然后d_{r}次多项式q_{r}的其他点完全随机的选取。对于任意的其他节点x,设置q_{x}(0)=q_{parent(x)}(index(x)),其他点随机选择来定义q_{x}。多项式被定义好之后,对于叶子节点x,我们将以下的秘密值给用户:

                                                       D_{x}=g^{\frac{q_{x}(0)}{t_{i}}},当i=att(x)时。

以上一组秘密值就是解密密钥D。

Decryption(E,D):解密过程为递归过程。首先定义一个递归算法DecryptNode(E,D,x),将密文E=(\gamma ,E{}',\left \{ E_{i} \right \}_{i\in \gamma }),私钥D,树中的一个节点x作为输入,输出一个G2中的元素或者\perp

        令i=att(x)。当节点是叶子节点时DecryptNode(E,D,x)=\left\{\begin{matrix} e(D_{x},E_{i}) =e(g^{\frac{q_{x}(0)}{t_{i}}},g^{s\cdot t_{i}})=e(g,g)^{s\cdot q_{x}(0)},if i\in \gamma & & \\ &\perp otherwise & \end{matrix}\right.

       当x不是一个叶子节点时,算法DecryptNode(E,D,x)过程如下:对于x的所有子节点z,调用DecryptNode(E,D,z)并保存输出为F_{z},令S_{x}为任意k_{x}大小的子节点z的集合,使得F_{z}\neq \perp,如果这样的集合不存在,则节点不满足,函数返回\perp。否则,计算如下:

                                      F_{x}=\prod_{z\in S_{x}}^{}F_{z}^{\Delta _{i},s{}'_{x}(0)}, i=index(z),s{}'_{x}=\left \{ index(z):z\in S_{x} \right \}

                                           =\prod_{z\in S_{x}}^{}(e(g,g)^{s\cdot q_{z}(0)})^{\Delta _{i,s{_{x}}'}(0)}

                                           =\prod_{z\in S_{x}}^{}(e(g,g)^{s\cdot q_{parent(z)}(index(z))})^{\Delta _{i,s{}'_{x}}(0)}

                                           =\prod_{z\in S_{x}}^{}e(g,g)^{s\cdot q_{x}(i)\cdot \Delta _{i,s{}'_{x}}(0)}

                                           =e(g,g)^{s\cdot q_{x}(0)}

最后返回结果。我们发现当访问树被满足时DecryptNode(E,D,r)=e(g,g)^{ys}=Y^{s}。因为E{}'=MY^{s},所以E{}'/Y^{s}就是我们解密出来的明文M。

KP-ABE的说明

        KP-ABE的Setup和Encryption过程和基本ABE一致,主要区别在于密钥生成和解密阶段,将基本ABE中的门限值替换成了细粒度的访问树控制结构,只有当密文中的属性满足密钥中嵌入的访问树时,用户才能解密该密文。根据密文中的属性和访问树的叶子节点开始匹配,层层递进直到根节点,若满足则可以恢复出根节点的秘密值y,从而计算出Y^{s}的值,最终解出明文M。

参考文献

GOYAL V, PANDEY O, SAHAI A, et al. Attribute-based encryption for fine-grained access control of encrypted data

  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是KP-ABE算法的Java实现示例: ```java import it.unisa.dia.gas.jpbc.Element; import it.unisa.dia.gas.jpbc.Pairing; import it.unisa.dia.gas.jpbc.PairingFactory; import it.unisa.dia.gas.jpbc.Field; import it.unisa.dia.gas.jpbc.Field.ElementPowPreProcessing; import it.unisa.dia.gas.plaf.jpbc.pairing.a.TypeACurveGenerator; import it.unisa.dia.gas.plaf.jpbc.pairing.parameters.PropertiesParameters; import it.unisa.dia.gas.plaf.jpbc.pairing.parameters.PropertiesParametersGenerator; import it.unisa.dia.gas.plaf.jpbc.util.ElementUtils; import java.util.ArrayList;import java.util.HashMap; import java.util.Map; public class KPABE { private Pairing pairing; private Field G1, GT, Zr; private Element g, h, f; private Map<String, Element> D; private Map<String, ElementPowPreProcessing> D_pre; private Map<String, Element> D1; private Map<String, ElementPowPreProcessing> D1_pre; public KPABE() { PropertiesParametersGenerator pg = new PropertiesParametersGenerator(); pg.init(new TypeACurveGenerator(3, 32)); PropertiesParameters params = pg.generate(); this.pairing = PairingFactory.getPairing(params); this.G1 = pairing.getG1(); this.GT = pairing.getGT(); this.Zr = pairing.getZr(); this.g = G1.newRandomElement().getImmutable(); this.h = G1.newRandomElement().getImmutable(); this.f = GT.newRandomElement().getImmutable(); this.D = new HashMap<String, Element>(); this.D_pre = new HashMap<String, ElementPowPreProcessing>(); this.D1 = new HashMap<String, Element>(); this.D1_pre = new HashMap<String, ElementPowPreProcessing>(); } public void setup(int n) { Element alpha = Zr.newRandomElement().getImmutable(); Element beta = Zr.newRandomElement().getImmutable(); Element g_alpha = g.powZn(alpha).getImmutable(); Element h_beta = h.powZn(beta).getImmutable(); Element f_alpha = f.powZn(alpha).getImmutable(); D.put("g_alpha", g_alpha); D_pre.put("g_alpha", G1.newElement().set(g_alpha).getImmutable().getElementPowPreProcessing()); D.put("h_beta", h_beta); D_pre.put("h_beta", G1.newElement().set(h_beta).getImmutable().getElementPowPreProcessing()); D.put("f_alpha", f_alpha); D_pre.put("f_alpha", GT.newElement().set(f_alpha).getImmutable().getElementPowPreProcessing()); for (int i = 1; i <= n; i++) { Element r = Zr.newRandomElement().getImmutable(); Element g_r = g.powZn(r).getImmutable(); Element h_r = h.powZn(r).getImmutable(); D.put("g_" + i, g_r); D_pre.put("g_" + i, G1.newElement().set(g_r).getImmutable().getElementPowPreProcessing()); D.put("h_" + i, h_r); D_pre.put("h_" + i, G1.newElement().set(h_r).getImmutable().getElementPowPreProcessing()); Element D1_i = g_alpha.mul(h_beta).mul(g_r).getImmutable(); D1.put("D1_" + i, D1_i); D1_pre.put("D1_" + i, G1.newElement().set(D1_i).getImmutable().getElementPowPreProcessing()); } } public Map<String, Element> keygen(String[] attrs) { Map<String, Element> sk = new HashMap<String, Element>(); Element r = Zr.newRandomElement().getImmutable(); Element D2 = g.powZn(r).getImmutable(); sk.put("D2", D2); for (String attr : attrs) { Element r_attr = Zr.newRandomElement().getImmutable(); Element D3_attr = g.powZn(r_attr).getImmutable(); Element D4_attr = D.get("h_" + attr).powZn(r).mul(h).powZn(r_attr).getImmutable(); sk.put("D3_" + attr, D3_attr); sk.put("D4_" + attr, D4_attr); } return sk; } public Element encrypt(String[] attrs, String message) { Element s = Zr.newRandomElement().getImmutable(); Element C0 = f.mul(pairing.pairing(g, h.powZn(s))).getImmutable(); Element C1 = g.powZn(s).getImmutable(); ArrayList<Element> C2_list = new ArrayList<Element>(); for (String attr : attrs) { Element C2_attr = D.get("g_" + attr).powZn(s).getImmutable(); C2_list.add(C2_attr); } Element C2 = ElementUtils.getProdOfElements(C2_list).getImmutable(); Element C3 = GT.newElement().setToHash(message.getBytes(), 0, message.getBytes().length).powZn(s).getImmutable(); return pairing.getGT().newElement().setToCipherText(C0, C1, C2, C3).getImmutable(); } public Element decrypt(Map<String, Element> sk, Element ct) { Element D2 = sk.get("D2"); ArrayList<Element> D3_list = new ArrayList<Element>(); ArrayList<Element> D4_list = new ArrayList<Element>(); for (String attr : sk.keySet()) { if (attr.startsWith("D3_")) { D3_list.add(sk.get(attr)); } else if (attr.startsWith("D4_")) { D4_list.add(sk.get(attr)); } } Element numerator = pairing.pairing(ct.get(1), D2).getImmutable(); ArrayList<Element> denominator_list = new ArrayList<Element>(); for (int i = 0; i < D3_list.size(); i++) { Element D3_i = D3_list.get(i); Element D4_i = D4_list.get(i); Element C2_i = ct.get(2).powZn(D3_i).mul(D4_i).getImmutable(); denominator_list.add(pairing.pairing(D_pre.get("h_" + i), C2_i)); } Element denominator = ElementUtils.getProdOfElements(denominator_list).getImmutable(); return ct.get(3).mul(numerator.div(denominator)).getImmutable(); } public static void main(String[] args) { KPABE kpabe = new KPABE(); kpabe.setup(5); Map<String, Element> sk = kpabe.keygen(new String[]{"1", "2", "3"}); Element ct = kpabe.encrypt(new String[]{"1", "2"}, "hello world"); Element m = kpabe.decrypt(sk, ct); System.out.println(m); } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值