《A Graduate Course in Applied Cryptography》Chapter 11 Public key encryption (2)ss-trapdoor function

本文详细解读了如何利用陷门函数在随机谕言机模型中构建一个语义安全的加密方案,通过Game理论证明其SS-CPA安全性,并探讨了安全定理的来源。重点讲解了哈希函数的理想化处理和敌手优势分析。

原文教材 与 参考资料:

        Boneh Dan , Shoup Victor . A Graduate Course in Applied Cryptography[J].

        该书项目地址(可以免费获取):http://toc.cryptobook.us/

        博客为对该书的学习笔记,并非原创知识,帮助理解,整理思路。
 

11.4 Encryption based on a trapdoor function scheme 

本小节该书介绍了如何使用陷门函数在随机谕言机模型下构造一个语义安全的加密方案。

废话不多说,该给给出的方案如下:

  • 该加密方案使用陷门函数的秘钥生成算法作为一个本方案秘钥生成算法。
  • 首先加密方选择随机数x , 用陷门公钥Pk加密随机数x得到y , 然后计算x的哈希值k , 最后使用对称加密算法以k作为密钥对消息m进行加密得到部分密文c, 输出(y , c)作为对m的最终加密结果密文。
  • 当接受方具备一个陷门私钥sk, 并收到密文(y,c)时,解密算法运行如下,首先使用sk解密y得到x,进一步,计算x的哈希值得到对称秘钥,最终使用对称算法得到消息m。

安全性证明:

这里是在随机谕言机模型下对该方案具备SS-CPA安全性进行证明,加密方案中的哈希函数作为一种随机谕言机O出现,挑战者在加密时需要使用哈希函数H时将直接向随机谕言机发起询问,由随机谕言机来回答哈希询问。并且,挑战者和敌手都能具有访问该随机谕言机的权限。

故,综合上述内容,该方案应该具备以下的安全属性(安全定理):

上述定理的来源,或者说为什么要如此定义安全性?

本质上我们在描述一个方案是安全的时候,其实我们说的是该方案每一个组件是安全的并且组合起来在某些已经公知的模型中也是安全的,这才是可证明安全。这里要和UC安全区分来看,UC注重的是每个组件之间的通用可组合,而安全规约这里注重的是在现有的安全模型下保持安全性。

首先,该方案是在随机谕言机模型下证明的,其中哈希函数此时被处理为一个随机谕言机,那么此时哈希函数的安全性已经被理想化,此刻,如果存在该单项陷门函数与语义安全的对称加密方案,那么该方案亦是语义安全的。

进一步,从挑战游戏上来说,如果存在一个SS敌手A在随机谕言机模型下能够攻击该方案,那么存在一个SS敌手B1可以攻击其中语义安全的对称加密方案,以及一个SS敌手B2能够攻击该陷门函数,其中B1,B2均可以调用A作为自己的子程序。

证明思路:有了上述的分析,证明思路更加清晰了,首先构造基于随机谕言机的Game,然后给出基本的敌手优势描述,进一步,在证明时将随机谕言机处理成为一个可以查询的表格结构,并使用Difference lemma (该引理的重要之处在于将两个不同分布的游戏放到同一个概率空间下,目的是通过Z事件概率刻画敌手区分Game的优势)。

证明下述不等式成立:

          

首先,定义Game 0,

                           

初始阶段:

       挑战者生成公钥对,并随机的选取对称秘钥x, 并使用公钥加密加密这个对称秘钥,就是一种秘钥封装机制。挑战者随机选择一个对称秘钥k, 并随机选择一个比特b,  并将这个(x, k)写入随机谕言机的实现表格Map。然后,将公钥pk发送给敌手A。

询问阶段:

    (1)加密询问:当挑战者收到一个加密请求时,挑战者访问随机谕言机表格使用初始的生成的对称秘钥k和选择的随机比特b进行加密,并将加密结果返回给敌手。

    (2)随机谕言机询问:不论是敌手还是挑战者都能够访问随机谕言机,输入x 随机谕言机返回一个对应的随机数。如果表格中存在则返回对应的值,如果表格中不存询问的x, 则现场产生一个随机的k返回。

定义Game 1:

Game 1 和 Game 0 区别不大,但是没有上述第3步骤,如下图:

                      

 即,此时随机语言谕言机实现表格中没有初始化的条目,这就意味着挑战者加密使用对称密钥并不一定在谕言机表格中有相应的x来询问对应。如果想要使得Game0 和 Game1 表现出相同的运行结果与过程,在Game 1中敌手必须询问Game 0中的x。我们定义这个事件为Z,根据Difference Lemma 引理,我们得到如下表达式:

                                             

如果Z发生,那么敌手的某一个随机谕言机请求就是y的逆,此时可以认为敌手攻破陷门函数。所以自然而然的,我们此处可以使用一个陷门函数敌手B来调用SS-RO敌手针对方案中使用的陷门函数进行攻击,显然此时B敌手的优势就是Z事件的概率。

 具体来说,此时可以比较方便的将挑战者改造成为一个陷门函数攻击游戏挑战者,然后构造陷门敌手B调用SS敌手A来于陷门函数攻击挑战者交互,如下图所示:

                               

 所以,得到陷门敌手描述:

                                                

进一步,在Game 1中,密钥k被用来加密挑战密文,得到密文c,如果说一个敌手能够攻破该对称加密方案,那么也一定能够攻击成功上述整个加密方案,也可以说,如果敌手A能够攻破上述整个方案那么一定存在一个针对该对称方案的SS敌手。

故,根据语义安全的定义,也很容易将上述Game 1改造成为一个SS的攻击游戏,所以得到下述敌手优势:

                                              

综上所述,下式成立。

 

在使用 Python 的 `rsa` 模块加载 RSA 公钥时,如果遇到 `ValueError: No PEM start marker 'b'-----BEGIN RSA PUBLIC KEY-----'' found` 错误,通常是因为程序未能正确识别公钥的 PEM 格式起始标记。该错误提示表明加载过程中未找到 `-----BEGIN RSA PUBLIC KEY-----` 标记,这是 RSA 公钥的标准 PEM 开始标识[^1]。 ### PEM 格式的正确格式 RSA 公钥的 PEM 格式必须包含以下结构: ``` -----BEGIN RSA PUBLIC KEY----- <PEM 编码的公钥数据> -----END RSA PUBLIC KEY----- ``` 若使用的是通用的 `-----BEGIN PUBLIC KEY-----` 而非 `-----BEGIN RSA PUBLIC KEY-----`,则某些库(如 `rsa` 模块)可能无法正确解析,导致加载失败。 ### 解决方案 1. **确保使用正确的 PEM 标记** 若使用的是 `-----BEGIN PUBLIC KEY-----` 标记,表示该密钥是通用的 SubjectPublicKeyInfo 格式(X.509 标准),而非传统的 RSA 专有格式。`rsa` 模块默认仅支持 `-----BEGIN RSA PUBLIC KEY-----` 格式。可以通过 OpenSSL 工具转换格式: ```bash openssl rsa -pubin -in public.pem -out public_rsa.pem ``` 2. **使用 `cryptography` 模块处理通用公钥** 如果希望加载 `-----BEGIN PUBLIC KEY-----` 格式的公钥,则应使用 `cryptography` 模块: ```python from cryptography.hazmat.primitives import serialization with open("public.pem", "rb") as key_file: public_key = serialization.load_pem_public_key( key_file.read() ) ``` 3. **验证密钥内容是否完整** 确保密钥文件或字符串中没有多余的空格、换行符或缺失内容。可以使用以下方式验证: ```python pem_data = b"""-----BEGIN RSA PUBLIC KEY----- MIIBCgKCAQEAuQLSUdK1ilu7SwQtffUGt... -----END RSA PUBLIC KEY-----""" from cryptography.hazmat.primitives import serialization public_key = serialization.load_pem_public_key(pem_data) ``` ### 加密操作示例(使用 `rsa` 模块) 在确保公钥格式正确后,可以使用 `rsa` 模块进行加密: ```python import rsa with open('public_rsa.pem', 'rb') as f: pem_data = f.read() public_key = rsa.PublicKey.load_pkcs1(pem_data) message = 'Secret message'.encode('utf-8') encrypted = rsa.encrypt(message, public_key) print("Encrypted:", encrypted) ``` ### 相关问题
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值