公钥可搜索加密及其python实现

目录

  • 公钥可搜索加密
  • 密码工具库
  • PEKSBoneh2004方案代码实现
  • Reference

公钥可搜索加密

公钥可搜索加密(Public-Key Encryption with Keyword Search,简称PEKS)定义如下:

  • S e t u p ( 1 λ ) → ( s k , p k ) \mathsf{Setup}(1^\lambda) \to (\it{sk}, \it{pk}) Setup(1λ)(sk,pk):初始化算法,输入安全参数 1 λ 1^\lambda 1λ,获取私钥 s k \it{sk} sk和公钥 p k \it{pk} pk
  • E n c ( p k , w ) → c \mathsf{Enc}(\it{pk}, w) \to c Enc(pk,w)c:关键词加密算法,输入公钥和文档关键词 w w w,输出文档关键词对应的密文 c c c
  • T d G e n ( s k , w ) → t d \mathsf{TdGen}(\it{sk}, w) \to \it{td} TdGen(sk,w)td:陷门生成算法,输入私钥和搜索关键词 w w w,输出搜索关键词对应的陷门 t d \it{td} td
  • T e s t ( t d , c ) → b \mathsf{Test}(\it{td}, c) \to b Test(td,c)b:测试算法,输入陷门和密文,输出布尔变量 b b b,当陷门和密文对应同一关键词时 b = 1 b=1 b=1,否则 b = 0 b=0 b=0

PEKSBoneh2004方案构造如下:
e : G 1 × G 1 → G 2 e : \mathbb{G}_1 \times \mathbb{G}_1 \to \mathbb{G}_2 e:G1×G1G2为双线性对,两个函数 H 1 : { 0 , 1 } ∗ → G 1 \mathsf{H}_1 : \{0, 1\}^* \to \mathbb{G}_1 H1:{0,1}G1 H 2 : G 2 → { 0 , 1 } log ⁡ p \mathsf{H}_2 : \mathbb{G}_2 \to \{0, 1\}^{\log p} H2:G2{0,1}logp为哈希函数。

  • S e t u p \mathsf{Setup} Setup:输入安全参数,该安全参数决定群 G 1 \mathbb{G}_1 G1 G 2 \mathbb{G}_2 G2的阶 p p p,随机挑选 α ← Z p ∗ \alpha \gets \mathbb{Z}^*_p αZp G 1 \mathbb{G}_1 G1的生成元 g g g,输出 p k : = [ g , h = g α ] {\it pk} := [g, h=g^\alpha] pk:=[g,h=gα] s k : = α {\it sk} := \alpha sk:=α
  • E n c \mathsf{Enc} Enc:输入公钥和关键词,随机挑选 r ← Z p ∗ r \gets \mathbb{Z}^*_p rZp,计算 t : = e ( H 1 ( w ) , h r ) t := e(\mathsf{H}_1(w), h^r) t:=e(H1(w),hr),输出 c : = [ g r , H 2 ( t ) ] c := [g^r, \mathsf{H}_2(t)] c:=[gr,H2(t)]
  • T d G e n \mathsf{TdGen} TdGen:输入私钥和关键词,输出 t d : = H 1 ( w ) α {\it td} := \mathsf{H}_1(w)^\alpha td:=H1(w)α
  • T e s t \mathsf{Test} Test:输入陷门和密文,记密文为 c = [ c 1 , c 2 ] c = [c_1, c_2] c=[c1,c2],若 H 2 ( e ( t d , c 1 ) ) = c 2 \mathsf{H}_2(e(\it{td}, c_1)) = c_2 H2(e(td,c1))=c2,输出 b : = 1 b := 1 b:=1,否则输出 b : = 0 b := 0 b:=0

验证正确性:
e ( t d , c 1 ) = e ( H 1 ( w ) α , g r ) = e ( H 1 ( w ) , g α r ) = e ( H 1 ( w ) , h r ) e( {\it td}, c_1) = e(\mathsf{H}_1(w)^\alpha, g^r) = e(\mathsf{H}_1(w), g^{\alpha r}) = e(\mathsf{H}_1(w), h^r) e(td,c1)=e(H1(w)α,gr)=e(H1(w),gαr)=e(H1(w),hr),进一步有 H 2 ( e ( t d , c 1 ) ) = c 2 \mathsf{H}_2(e(\it{td}, c_1)) = c_2 H2(e(td,c1))=c2

直觉上(非理论层面,非严谨数学思维)对方案构造安全性进行分析:将 H 1 \mathsf{H}_1 H1当成随机谕言机,利用 H 1 \mathsf{H}_1 H1的单向性,敌手 A \mathscr{A} A很难根据 t d {\it td} td逆推出 w w w,同样很难根据 c c c逆推出 w w w

为什么不直接使用 c : = H ( w ) c := \mathsf{H}(w) c:=H(w) t d : = H ( w ) {\it td} := \mathsf{H}(w) td:=H(w)的形式?注意,在该形式中,即使敌手 A \mathscr{A} A没有私钥 α \alpha α,它同样也可以生成有效陷门 t d {\it td} td;但在PEKSBoneh2004方案中,若 A \mathscr{A} A没有私钥 α \alpha α,那么它无法生成正确的陷门 t d {\it td} td

为什么不直接使用 c : = H ( k , w ) c := \mathsf{H}(k, w) c:=H(k,w) t d : = H ( k , w ) {\it td} := \mathsf{H}(k, w) td:=H(k,w)的形式,然后在加密方和搜索方共享一条密钥 k k k?注意,该形式存在密钥管理问题,若有 n n n个加密方,那么搜索方需要将 k k k共享给这 n n n个加密方,加密方有可能是普通用户,不具备安全高防性,其易遭受黑客攻击,从而泄露 k k k。对比之下,在PEKSBoneh2004方案中,加密方仅需持有公钥,私钥泄露的风险大大减小。

并且上述两个做法 w w w对应的 c c c是固定的,若两个加密方同时加密同一 w w w,那么它们产生的两个密文是完全一样的,这显得有点不“安全”,监听者无需攻击服务器(一般假设云服务器具有安全高防性,需重点防范的是监听),仅需监听数据就可以自己对密文相关性进行一个分析。一种粗糙的应对策略是利用服务器的 p k ′ {\it pk}' pk二次加密 c c c,但这样做服务器需要维护一条公钥 p k ′ {\it pk}' pk,这增加了云服务商的花费开销,显得有点“不理想”。云服务商可能仅想提供计算服务,由搜索方自己去维护自己的公钥 p k {\it pk} pk。(至于防陷门监听,可以利用对称加密AES,注意,公钥可搜索加密在上传密文阶段是 n n n 1 1 1,而在搜索阶段是 1 1 1 1 1 1。)

密码工具库

PEKSBoneh2004方案用到双线性对,这里推荐一个实用的python密码工具库charm-crypto,该工具库由约翰斯·霍普金斯大学科研人员开发,© Copyright 2013, Johns Hopkins University ISI. Last updated on Feb 20, 2018. 写论文若使用该工具进行科研实验,请在Reference中标明

@article{charm13,
year={2013},
issn={2190-8508},
journal={Journal of Cryptographic Engineering},
volume={3},
number={2},
doi={10.1007/s13389-013-0057-3},
title={Charm: a framework for rapidly prototyping cryptosystems},
url={http://dx.doi.org/10.1007/s13389-013-0057-3},
publisher={Springer-Verlag},
keywords={Applied cryptography; Protocols; Software; Privacy},
author={Akinyele, Joseph A. and Garman, Christina and Miers, Ian
and Pagano, Matthew W. and Rushanan, Michael
and Green, Matthew and Rubin, Aviel D.},
pages={111-128},
}

项目地址:http://charm-crypto.io/

PEKSBoneh2004方案代码实现

#coding=utf-8

from charm.toolbox.pairinggroup import PairingGroup, ZR, G1, G2, GT, pair
import hashlib

Hash1pre = hashlib.md5
def Hash1(w):
    # 先对关键词w进行md5哈希
    hv = Hash1pre(str(w).encode('utf8')).hexdigest()
    print(hv)
    # 再对md5值进行group.hash哈希,生成对应密文
    # 完整的Hash1由md5和group.hash组成
    hv = group.hash(hv, type=G1)
    return hv

Hash2 = hashlib.sha256

def Setup(param_id='SS512'):
    # 代码符号G1 x G2 →  GT
    group = PairingGroup(param_id)
    # 方案选用的是对称双线性对,故G2 = G1
    g = group.random(G1)
    alpha = group.random(ZR)
    # 生成私钥与公钥并进行序列化
    # Serialize a pairing object into bytes
    sk = group.serialize(alpha)
    pk = [group.serialize(g), group.serialize(g ** alpha)]
    return [sk, pk]

def Enc(pk, w, param_id='SS512'):
    group = PairingGroup(param_id)
    # 进行反序列化
    g, h = group.deserialize(pk[0]), group.deserialize(pk[1])
    r = group.random(ZR)
    t = pair(Hash1(w), h ** r)
    c1 = g ** r
    c2 = t
    # 对密文进行序列化
    print(group.serialize(c2))
    return [group.serialize(c1), Hash2(group.serialize(c2)).hexdigest()]

def TdGen(sk, w, param_id='SS512'):
    group = PairingGroup(param_id)
    sk = group.deserialize(sk)
    td = Hash1(w) ** sk
    # 对陷门进行序列化
    return group.serialize(td)

def Test(td, c, param_id='SS512'):
    group = PairingGroup(param_id)
    c1 = group.deserialize(c[0])
    c2 = c[1]
    print(c2)
    td = group.deserialize(td)
    return Hash2(group.serialize(pair(td, c1))).hexdigest() == c2


if __name__ == '__main__':
    # 'SS512'是对称双线性对
    param_id = 'SS512'
    [sk, pk] = Setup(param_id)

    group = PairingGroup(param_id)

    c = Enc(pk, "yes")
    td = TdGen(sk, "yes")
    assert(Test(td, c))
    td = TdGen(sk, "no")
    assert(not Test(td, c))
    c = Enc(pk, "Su*re")
    assert(not Test(td, c))
    c = Enc(pk, "no")
    assert(Test(td, c))

    c = Enc(pk, 9 ** 100)
    td = TdGen(sk, 9 ** 100)
    assert(Test(td, c))
    td = TdGen(sk, 9 ** 100 + 1)
    assert(not Test(td, c))

Reference

[1] Dan Boneh, Giovanni Di Crescenzo, Rafail Ostrovsky, et al. Public Key Encryption with Keyword Search[C]// Advances in Cryptology - EUROCRYPT 2004, International Conference on the Theory and Applications of Cryptographic Techniques, Interlaken, Switzerland, May 2-6, 2004, Proceedings. 2004.
[2] 双线性对映射 概念理解

你可能感兴趣的:(现代密码学基础)