代理重加密原理与实践
主页
- 个人微信公众号:密码应用技术实战
- 个人博客园首页:https://www.cnblogs.com/informatics/
引言
2022年12月,人工智能迎来了一件大事,OpenAI的ChatGPT横空诞生,成为了现象级产品。如果说算力是人工智能的发动机,那么数据则是人工智能的Gasoline
。
互联网平台的封闭导致了信息孤岛
, 从而降低了数据公开流通,和数据要素价值,数据流通是实现数据社会化利用和实现数据资源价值的必然路径。随着国内[数据二十条][数据二十条]政策落地,支持依法依规在场内场外采取开放、共享、交换、交易
等方式流通数据
,为数据共享
提供了法律和政策指导,推动了数据开放、流通和共享的发展。
数据二十条对数据安全提出了一定的要求:
- 数据安全保护:在数据共享过程中,必须采取适当的安全措施,保护数据的机密性、完整性和可用性,防止未经授权的访问、使用和泄露。
- 数据访问和使用权限:数据共享应该建立明确的访问和使用权限,确保只有授权的用户可以访问和使用数据,并限制数据的滥用和不当使用。
- 数据共享协议和契约:数据共享应该建立在明确的协议和契约基础上,明确各方的权利和责任,确保数据共享的合法性和可持续性。
本文将要介绍的技术主要针对数据安全保护
,在数据共享过程中保证数据的机密性
。
代理重加密定义
代理重加密(Proxy Re-encryption, 简称PRE)方案是一种密码系统,允许第三方(代理)修改为某一方(数据提供方
)加密的密文,以便其他方(数据使用方
) 能够解密该密文。
PRE方案主要有以下特点:
- 委托(Delegation)- 允许消息接收者(密钥持有者)基于他的密钥和被委托用户的密钥生成一个重加密密钥。代理将使用这个重加密密钥作为输入,通过重加密函数将密文转换为被委托用户的密钥。非对称代理重加密方案有双向和单向两种类型。
- 传递性(Transitivity)- 传递性代理重加密方案允许对密文进行无限次的重加密。例如,一个密文可以从Bob重新加密为Charlie,然后再从Charlie重新加密为David,依此类推。非传递性方案只允许对给定密文进行一次(或有限次数)的重加密。大多数已知的方案都是双向和传递性的。目前,唯一已知的单向传递性代理重加密是通过同态加密实现的。
PRE方案常用于云环境下的数据安全共享。
无PRE数据安全共享
在下图中,Alice为数据提供方,Bob为数据使用方,Alice和Bob分别维护自己的加密公私钥。
- Alice加密数据上传到云存储
- 当Alice需要向Bob共享数据时,需要获取Bob的加密公钥
- Alice使用Bob的加密公钥对数据进行加密,并上传到云存储,如:
密文数据 for Bob
- Bob下载密文数据,并本地解密获取明文数据
使用PRE进行数据共享
- Alice将数据加密,并将加密后的数据上传到云存储
- 当Alice需要向Bob共享数据时,需要获取Bob的加密公钥
- Alice生成重加密密钥,并发送给代理重加密服务(Proxy Re-encryption Service)
- 代理重加密服务基于重加密密钥和步骤1中的加密数据,生成重加密密文数据
- Bob下载密文数据,并使用本地私钥进行解密,获取明文
对比 \ 数据共享 | 不使用PRE | 使用PRE |
---|---|---|
性能 | 低,需要数据提供者进行本地加密, 性能依赖于本地算力 |
高,代理重加密服务部署在云端, 可以借助云计算能力 |
易用性 | 中 | 中,对于数据提供者和数据使用者来说, 难度与不适用PRE相差不大 |
复杂度 | 低,基于基础密码算法, 复杂度相对较低 |
依赖于PRE方案和Proxy服务, 流程较为复杂,有一定的实现和运维难度 |
安全性 | 高 | 较高,云厂商和数据使用方存在合谋风险,但攻击有限 |
代理重加密原理
基于公钥算法的PRE方案
代理重加密方案涉及五元组<KeyGen, Encrypt, ReGenKey, ReEncrypt, Decrypt>
- KeyGen:本地密钥生成函数
- Encrypt: 数据加密函数
- ReGenKey:重加密密钥生成函数
- ReEncrypt:数据重加密函数
- Decrypt:数据解密函数
- 数据提供方Alice和数据使用方Bob使用KeyGen函数,分别生成本地公私钥
- Alice使用Encrypt函数对明文信息M进行加密,并将密文数据C上传到代理重加密服务Proxy
- 数据使用方提供加密公钥,并发送给Alice
- Alice使用ReGenKey函数,生成针对Bob的重加密密钥,并发送给Proxy
- Proxy使用ReEncrypt,并基于密文数据C和重加密密钥,生成新的密文数据:重加密密文数据
- Bob获取重加密密文数据,并使用本地私钥进行解密
方案构造和原理解析
-
初始化步骤(密钥生成&准备待共享数据)
-
Alice生成本地公私钥: \((pk_A, sk_A), pk_A = g^{sk_A}\)
-
待共享数据 \(M\)
-
Bob公私钥: \((pk_B, sk_B), pk_B = g^{sk_B}\)
-
-
Alice加密数据
- 选取随机数\(r\)
- 计算密文二元组:\(C = (C_1, C_2) = (g^r, M.{pk_A}^r)\)
- 将\((pk_A, C)\)发送给Proxy
-
Alice生成重加密密钥
- 获取Bob公钥\(pk_B\)
- 生成重加密密钥:$rk = \frac{sk_A}{H({pk_B}^{sk_A})} $
- 将\(rk\)发送给Proxy
-
Proxy代理重加密
- 从Alice收到的数据有\((pk_A, C, rk)\)
- Alice公钥\(pk_A\)
- 密文数据:\(C\)
- 重加密密钥\(rk\)
- 计算密文二元组:$C^{'} = (C{_1}^{'}, C{_2}^{'}) = (C{_1}^{rk}, C2) $
- 从Alice收到的数据有\((pk_A, C, rk)\)
-
Bob解密数据:
- Bob从Proxy接收到密文数据:\(C^{'}\)
- 计算明文:\(M^{'} = \frac{C{_2}^{'}}{({C{_1}^{'}})^{H({pk_A}^{sk_B})}}\)
- 这里的\(M' = M\)即为待共享数据
-
正确性验证
- 计算\(M' = \frac{C{_2}^{'}}{({C{_1}^{'}})^{H({pk_A}^{sk_B})}} = \frac{C_2}{C1^{rk.H({pk_A}^{sk_B})}} =\frac{C_2}{C1^{sk_A}} = \frac{M.{pk_A}^r}{g^{r.sk_A}} = \frac{M.{g^{{sk_A}.r}}}{g^{r.sk_A}}\)
- 分子分母存在公约数: \(g^{{sk_A}.r} = g^{r.sk_A}\)
- 约去公约数后,得到:\(M' = M\)
经过公式推导,可以看出,Bob能够成功解密。
基于对称算法的PRE方案
基于对称算法的PRE方案
结合了对称算法和非对称算法两种加密体制的优点。使用对称算法
对共享明文数据加密,保证加密性能;使用非对称算法
对对称密钥进行保护,保证密钥协商。
基于对称算法的PRE方案涉及8元组:<SymKeyGen, SymEncrypt, SymDecrypt, KeyGen, Encrypt, ReGenKey, ReEncrypt, Decrypt>
- KeyGen, Encrypt, ReGenKey, ReEncrypt, Decrypt与前文同,不再赘述
- SymKeyGen:对称算法密钥生成函数
- SymEncrypt:对称加密函数
- SymDecrypt:对称机密函数
优化版代理重加密关键流程如下:
- 数据提供方和数据使用方使用KeyGen函数,分别生成本地公私钥。同时Alice生成对称密钥(随机数)
- Alice使用Encrypt函数对明文信息M进行加密,并将密文数据C上传到代理重加密服务Proxy
- 数据使用方提供加密公钥,并发送给Alice
- Alice使用ReGenKey函数,生成针对Bob的重加密密钥,并发送给Proxy
- Proxy使用ReEncrypt,并基于密文数据C和重加密密钥,生成新的密文数据:重加密密文数据
- Bob获取重加密密文数据,并使用本地私钥进行解密
方案构造和原理解析
-
初始化步骤(密钥生成&准备待共享数据)
-
Alice生成本地公私钥 \((pk_A, sk_A), pk_A = g^{sk_A}\)
-
待共享数据 \(M\)
-
Bob公私钥: \((pk_B, sk_B), pk_B = g^{sk_B}\)
-
-
Alice加密数据
- 选取随机数\((e,u,r)\), \(E = g^e, U = g^u\)
- 生成对称密钥:\(K = F({pk_A}^{e+u})\), 其中\(F\)为转换函数,可以将椭圆曲线的点映射为固定长度的字节数据(如SM4密钥长度为16)
- 使用对称算法加密数据: \(C = SymEncrypt(M, K)\)
- 将\(C\), ${C_K}=({E, U}) $发送给Proxy
-
Alice生成重加密密钥
- 生成随机数\(b, B = g^b\) 并获取Bob公开的公钥\(pk_B\)
- 计算$d = Hash(B || pk_B || {pk_B}^{sk_A}) $
- 生成重加密密钥:\(rk = {sk_A}.{d^{-1}}\)
- 将\(({rk, B})\)发送给Proxy
-
Proxy代理重加密
- Proxy从Alice两次收到的消息包含\({E, U, rk, B}\), 首先计算\(E' = E^{rk}, U' = U^{rk}\)
- 生成\(C{_K}^{} = (E', U')\)
- 将\((B, C{_K}^{}, C)\) 发送给Bob(或由Bob下载)
-
Bob解密数据:
- 计算\(d = Hash(B || pk_B || {pk_A}^{sk_B})\)
- 通过计算获取对称密钥K, $ K = F(E'.U')^d$
- 解密获取M,\(M = SymDecrypt(C, K)\)
经过公式推导,可以看出,Bob能够成功解密
实践&应用
下面我们以基于对称算法的PRE方案
为例进行代码介绍,代码采用golang语言,其中非对称算法使用了国密sm2
, 哈希算法为sm3
.
- 下载PRE密码包
# 下载practical-crypto
➜ wkdir git clone https://github.com/warm3snow/practical-crypto.git
正克隆到 'practical-crypto'...
remote: Enumerating objects: 873, done.
remote: Counting objects: 100% (383/383), done.
remote: Compressing objects: 100% (262/262), done.
接收对象中: 100% (873/873), 8.31 MiB | 28.00 KiB/s, 完成.
处理 delta 中: 100% (382/382), 完成.
关键函数定义如下:
func KeyGen() (*sm2.PrivateKey, *sm2.PublicKey, error) {}
func Encrypt(r *big.Int, pk *sm2.PublicKey, m []byte) ([]byte, error) {}
func ReGenKey(r *big.Int, pkA, pkB *sm2.PublicKey, alpha []byte) *big.Int {}
func ReEncrypt(cipher []byte, skAB *big.Int) ([]byte, error) {
func Decrypt(cipher []byte, skB *sm2.PrivateKey, alpha []byte) ([]byte, error) {}
- 运行PRE程序
# 切换到PRE代码目录
➜ wkdir cd practical-crypto/advanced_crypto/pre
# 运行测试代码
➜ pre git:(master) go test -v -test.run=TestPre
=== RUN TestPre
pre_test.go:21: Test PRE
pre_test.go:22: 待共享数据明文 M: hello PRE!
pre_test.go:37: Alice加密数据: 2cbfa60e52a5b53dd34aa21baba69f51
pre_test.go:38: Alice加密数据 Capsule: 7b2245223a7b224375727665223a6e756c6c2c2258223a31363331383730353633373430343430363339353132303230343032383735373534393136353032363536373030343138343330373938333439363839353738313232373530303832323635352c2259223a37363931333331323931363136373736303938383735343938343033323532303238353837333639333739383636323832363535333239303230363235373833333230353334343239383335397d2c2256223a7b224375727665223a6e756c6c2c2258223a31373738393037343035363836313239373636373536393633383530323732373833313735343633353131333032333033343635303631383136393231333338393233313131383531363238332c2259223a35393434353333323435363535353536393231363934353637393130373738353236353332343932333734383834373337363436323737383237383232333435303831373833353436323933337d2c2253223a3231333636373534353236393537303931373634303236363339363735363830353833343830313132383633373134343633363732313539343330383734393139353734363737313737343132363136303433333231333634353933343630323438393639383830333633383530323935373536303935393632343832333534353031303933393637363937333034343030393735303339353133363436353430363834353334313836303236337d
ReGenKey d: 86776578942220434879492507132922592428947784438620508923301187582598416130155
ReGenKey dInv: 97733987058783820900214716828113790131983940598302895601690744252191835809539
pre_test.go:47: Proxy重加密数据 Capsule': 7b2245223a7b224375727665223a6e756c6c2c2258223a3131343930313439353438343139353332343539323435393339303933313231353934383630343730313733333139333739303433343931343933323030313938353232373037353130393132302c2259223a3131333437343133373131303233373930363930363935353431303432313535333833303930353332353239383139313338363139313830373638393039383231343530373536333632313733357d2c2256223a7b224375727665223a6e756c6c2c2258223a32343633323734373333313336363735313335393535353138303334373838303032343637333239323431393532393430373037303431303030303237303934393635323439313438363638302c2259223a37393935323734323930383737373433303930383232343331383730323931353234303038363038343130343131373039393937353331363034303532393638373234363332303336363835347d2c2253223a3231333636373534353236393537303931373634303236363339363735363830353833343830313132383633373134343633363732313539343330383734393139353734363737313737343132363136303433333231333634353933343630323438393639383830333633383530323935373536303935393632343832333534353031303933393637363937333034343030393735303339353133363436353430363834353334313836303236337d
Decrypt d: 86776578942220434879492507132922592428947784438620508923301187582598416130155
pre_test.go:53: Bob解密数据 M: 492997048111525925111073
pre_test.go:54: 明文Msg: 492997048111525925111073
pre_test.go:58: Bob解密数据 M: hello PRE!
--- PASS: TestPre (0.01s)
PASS
ok github.com/warm3snow/practical-crypto/advanced_crypto/pre 0.403s
总结
本文从整体上介绍了代理重加密PRE的基本定义、方案原理、并在最后通过golang代码实现了代理重加密方案(非优化版),希望读着对代理重加密有个初步的认识。
声明:文中提到的代码实现仅用于技术交流和基本演示,不推荐在生产环境中使用,如使用请自担风险!!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?