KP-ABE和CP-ABE(步骤详细讲解)

KP-ABE是密文-》属性集,私钥-》访问结构。属性集满足访问结构才能解出最终的明文。
CP-ABE是密文-》访问结构,私钥-》属性集。属性集满足访问结构才能解出最终的明文。这里面的属性集是私钥,包含了数据请求者的属性,用来解访问控制树,最终得到根节点的秘密数S,然后带入公式3解密就能得到明文。

在密文策略基于属性加密方案中,最难理解的过程莫过于访问树的构造和从访问树中解密出访问树的秘密数,本文从访问树的构造和从访问树中解密出访问树的秘密数进行讨论。

  1. 构造访问树
  在CP-ABE方案中,访问树用于隐藏源数据的加密密钥,其形状结构如其名一样,是一棵树。其叶子节点为数据所有者设定的属性和属性值以及父节点传于此节点的秘密值,并对其加密处理,只有数据访问者拥有此属性方可解密出此节点的秘密值;非叶子节点为门限节点,数据访问者需满足此门限最低值方可解密此节点秘密值,例如门限为3/5,此节点有5个子节点,数据访问者需至少满足3个子节点才能解密出秘密值。
  如下图所构造的访问树,能解密此访问树加密的源数据,数据访问者需满足的属性是:第一种:(“计算机学院” 且 “硕士” 且 “研二”)和 “教师”(此属性结合可能不存在,因为教师和研二不存在且关系) ,第二种:“教师” 和(“网络实验室” 或 “云实验室”),第三者:(“计算机学院” 且 “硕士” 且 “研二”)和(“网络实验室” 或 “云实验室”);否则无法访问。
  如何构造这样的一棵访问树?
  从根节点开始,其门限值为2,孩子节点有3个,随机生成一个多项式,其最高次数为门限值少1,故根节点的最高次数为1,然后将常数项设置为秘密数(秘密数为需要秘密保存的数);如此根节点随机的多项式为f(x)=5+3x,秘密数为5。此外,将根节点的孩子节点从左至右依次标记为1,2,3,.....,将节点标记值代入f(x)函数中,所得值(即生成新的秘密值)传给该标记的孩子节点秘密保存;故“3/3”节点(左边第一个节点)标记为1,传给“3/3”节点的秘密值f(1)=5+3*1=8,中间“教师”节点(中间节点)标记为2,传给“教师”节点的秘密值f(2)=5+3*2=11,“1/2”节点(右边节点)标记为3,传给“1/2”节点的秘密值为f(3)=5+3*3=14。

  “3/3”节点和“1/2”节点在接收到父节点传来的值后,按照上述方式生成随机多项式,将常数项设置为父节点传来的值,此外也按照上述方式生成新的秘密值并将它传给子节点,数据如图所示(对于非叶子节点,都按照此方式进行)。对于叶子节点,在接受到父节点的秘密值后,用此叶子节点的属性对秘密值进行加密处理。

如下图所示,在进行秘密值分发之前,加密者先随机选择秘密值s(以s=5)为例,然后,先从根节点构造多项式f(x)=ax(n-1)+bx(n-2)…+c,其中n表示的为(t,n)门限的的t-1。如果为"AND"门,取值为其子树的数目-1,"OR"结构取值为1即可,常数项c设置为秘密值s。从左到右依次编号,带入1,2,3…来进行秘密值分发,第一层分发完成之后进入第二层进行秘密值分发,按照此规律完成加密过程。
至此,访问树已构造完成!
在这里插入图片描述

  1. 从访问树中解密出访问树的秘密数

    数据访问者需满足访问树方可解密出访问树的秘密值,对于上述访问树,数据访问者需满足以下属性集中的一个:(计算机学院、硕士、研二、教师(此属性结合可能不存在,因为教师和研二不存在且关系))、(计算机学院、硕士、研二、网络实验室)、(计算机学院、硕士、研二、云实验室)、(教师、网络实验室)、(教师、云实验室)。若上述属性集中某一个或多个(至少一个)为数据访问者属性集的子集,则能解密出秘密值,下面开始解密处理。

    对于叶子节点,在数据访问者属性集中寻找出和此节点属性与属性值一致的属性,用找出的属性解密出此节点的秘密值(即公式1),当然不能完全解密出,他是秘密值和加密时对此属性设置的加密值的乘积。

    解密出叶子节点后,开始解密其父节点(非叶子节点),在解密出叶子节点后,即可得到多对值;如在上述访问树的“3/3”节点,其孩子节点解密出三个值19,44,83(推理过程忽略随机数),在生成这三个数时,f(1)=19,f(2)=44,f(3)=83,其中f(x)=8+4x+7x^2(解密时并不知道此多项式,只知道后面的三个点),因此在f(x)上有三个点是(1,19),(2,44),(3,83);因为此节点存储的秘密值是多项式的常数项,即f(0)=秘密值,故我们需要根据这三个点得到0所对应的值是多少,根据拉格朗日公式就能求出0所对应的值,即解密出秘密值(即公式2);对于非叶子节点均可按照上述方式解密出秘密值,在根节点处解密出整个树所隐藏的秘密值(是秘密值和加密时对此属性设置的加密值的乘积,所有节点解密出的秘密都存在一个随机数,解密出的值都是随机数和秘密值的乘积,只是讲述过程中为了方便忽略了随机数,最后根节点解密出的随机数在最后的解密过程中会抵消掉(公式3))。

    另外需要说明的是“3/3”节点是一个3个孩子节点、门限值为3的节点,相当于且关系,数据访问者需解密出所有的孩子节点方可用拉格朗日公式解密出常数项(即秘密值);“1/2”节点是一个2个孩子节点、门限值为1的节点,故为或关系,数据访问者只满足其中一个孩子节点即可解密出秘密值(秘密值就是孩子节点解密出的秘密值,因为根据随机多项式生成规则,多项式的最高次数为门限值少1,门限值为1,故最高次数为0,即常数项);若如“2/3”这样的节点,既非且关系,也非或关系,3个孩子节点,门限值为2,若需解密出此节点的秘密值,数据访问者需解密出三个孩子节点中的两个节点即可解密出孩子节点。
    在这里插入图片描述
    3.CP-ABE完整流程
    3.1.初始化
    在这里插入图片描述
    3.2.加密
    在这里插入图片描述
    用秘密值分发得到的子秘密值qy(0)进行加密即可得到密文CT,其中H(att(y))值将属性att(y)映射到G域。

3.3.私钥生成
授权机构会根据用户属性,产生相对应的属性**,用于解密
在这里插入图片描述
3.4.解密
解密分成两部分,先解密叶子节点:
在这里插入图片描述
再进行拉格朗日插值
在这里插入图片描述
进而进行最终解密得到秘密值s
在这里插入图片描述
4.KP-ABE流程
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

参考文献:1.https://www.pianshen.com/article/46761519950/
2.https://blog.csdn.net/qq_37272891/article/details/107008073?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
3.KP-ABE论文名称:Attribute-Based Encryption for Fine-Grained Access Control of Encrypted Data

  • 16
    点赞
  • 108
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是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); } } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值