同态加密与 Paillier/RSA
- 本文作者: wdxtub
- 本文链接: http://wdxtub.com/flt/flt-03/2020/12/02/
白话同态加密
虽然同态加密即使现在听起来也很陌生,但是其实这个概念来自 1978 年,由 RSA 算法的发明者的 R 和 A 以及 Dertouzos 提出。具体的定义如下:
A way to delegate processing of your data, without giving away access to it.
翻译成人话就是传统的加密方法和数据处理方法是互斥的,比如我需要计算两个数字的和(1 和 2),如果加密了之后,就无法对密文进行计算;如果想要进行计算,就必须知道这两个数字是 1 和 2。如果数据拥有方和计算方是同一方,那么知道 1 和 2 没啥问题;但如果数据拥有方和计算方并非同一方,并且数据拥有方还不想让计算方知道这两个数字是 1 和 2,这个时候就是同态加密发挥作用的时候了。
同态加密将数据的处理和数据本身解耦了:计算方拿到的是加密之后的数字,但是依然可以相加,相加之后把结果告诉数据拥有方,最终数据拥有方解密就可以知道最终的计算结果。
同态加密的这个特点使得云服务厂商非常在意,因为这一举解决了用户担心云服务厂商窃取数据的担心(因为加密了除了计算没法做其他事情),并且因为加密计算本身耗费更多计算资源,还可以变相提高营收。
总结一下:同态加密使得数据可以在加密的状态下进行计算,至于支持什么计算,如何进行计算,我们接下来继续讲。
定义同态加密
先假设一个场景:我想要处理一大批数据,如果在本地用明文要 100 个小时,这个时间太长了,所以我需要借助云计算的力量。但是因为这批数据很敏感,包括了我从小到大每一分每一秒的心情和各类身体指标,我不希望云计算平台能够直接获取到,这样我就感觉自己没有隐私了,所以我需要使用同态加密,让云计算平台在加密的情况下计算(假设只需要 1 个小时),我拿到加密计算的结果再解密得到真实结果。那么问题来了,这个过程需要几步?
- 我在本地生成用来加密数据的 Key
- 我用 Key 和 Encrypt 算法加密本地的数据,记为
EncData = Encrypt(Key, Data) - 我告诉云平台需要如何计算数据,记为函数
F() - 云平台进行计算 Evaluate,即
Evaluate(F(), EncData) = Encrypt(Key, F(Data)),记为ProEncData - 云平台将
ProEncData发回给我 - 我用密钥进行解密 Decrypt,得到
F(Data) = Decrypt(Key, ProEncData),也就是最终结果
在以上六个步骤中,至少有四个函数是必须的:
- 生成密钥的函数:本地执行,生成密钥
- Encrypt 函数:本地执行,加密数据,加密之后的数据不会暴露源数据的信息
- Evaluate 函数:用来执行用户给定的计算函数
F(),是唯一由云平台运行的函数 - Decrypt 函数:本地执行,解密数据
根据支持的 F() 的不同,同态加密分成了两类:
Fully Homomorphic Encryption, FHE:这种方式下,任何
F()都可以,只要这个算法能够被计算机实现即可。不过这个计算开销非常大,目前暂无实际应用。注:Gentry 在 2009 年给出过一个实现Somewhat Homomorphic Encryption, SWHE:这种方式下,只支持某些特定的
F()
(比如只支持加法/乘法,并且只能执行有限次数)。这个方案有比较大的限制,但也因此计算开销较小,已经可以在实际中使用
- 乘法:RSA, Elgamal
- 加法:Paillier
接下来我们会详细看看 Paillier 算法和 RSA 算法,对加法同态和乘法同态有更加深入的理解。
Paillier 算法
因为有了前面的分析,我们知道一个同态加密算法需要四个函数:密钥生成、加密、解密、同态运算,针对 Paillier 算法,我们一项一项来看一下。
这里我们也准备了不同语言版本的实例:
注:实际实现的过程中,一般不会直接实现 gcd 和 lcm 函数,而是采用一些替代的计算,具体参考上面链接中的源码。
密钥生成
总共有如下几个步骤:
- 随机选择两个质数 p 和 q 满足 |p|=|q|=τ|p|=|q|=τ,这个条件保证了 p 和 q 的长度相等。
- 计算 N=pqN=pq 和 λ=lcm(p−1,q−1)λ=lcm(p−1,q−1),注:lcm 表示最小公倍数
- 随机选择 g∈Z∗N2g∈ZN2∗,满足 gcd(L(gλmodN2),N)=1gcd(L(gλmodN2),N)=1,注:gcd 表示最大公约数;Z 表示整数,下标表示该整数集合里有多少个元素;L(x)=x−1NL(x)=x−1N
- 公钥为 (N,g)(N,g)
- 私钥为 λλ
加密
对于任意整数 m∈ZNm∈ZN,任意选择随机数 r∈Z∗Nr∈ZN∗,密文 C=E(m)=gmrNmodN2C=E(m)=gmrNmodN2
解密
对于密文 C∈Z∗N2C∈ZN2∗,解密得到明文 m 的计算如下:
m=L(CλmodN2)L(gλmodN2)modNm=L(CλmodN2)L(gλmodN2)modN
加法同态
对于任意明文 m1,m2∈ZNm1,m2∈ZN,假设 E(m1)=gm1rN1modN2E(m1)=gm1r1NmodN2 和 E(m2)=gm2rN2modN2E(m2)=gm2r2NmodN2,有
E(m1)E(m2)=gm1+m2(r1r2)NmodN2=E(m1+m2modN)E(m1)E(m2)=gm1+m2(r1r2)NmodN2=E(m1+m2modN)
这个性质表明 Paillier 加密方案具有加法同态性。
RSA 算法
RSA 算法作为最为知名的非对称加密算法,想必大家都有一定的了解,这里我们仍然以针对密钥生成、加密、解密、同态运算四个步骤,一项一项来看一下。同样可以参考下面的代码实例:
密钥生成
- 随机找两个质数 P 和 Q,越大越安全,并计算乘积 n=P∗Qn=P∗Q。P 和 Q 的乘积的二进制位数代表 RSA 加密的位数,一般来说都要有 1024 或 2048 位。
- 计算 n 的欧拉函数 ϕ(n)ϕ(n),表示在小于等于 n 的正整数中,与 n 构成互质关系的数的个数。比如 1~8 中,和 8 互质的有 1,3,5,7,所以 ϕ(8)=4ϕ(8)=4,如果 p 和 q 为质数,那么他们的乘积的欧拉函数有一个特殊的性质,公式为 ϕ(n)=ϕ(P∗Q)=ϕ(P−1)ϕ(Q−1)=(P−1)(Q−1)ϕ(n)=ϕ(P∗Q)=ϕ(P−1)ϕ(Q−1)=(P−1)(Q−1)
- 选取 e,要大于 1 小于 ϕ(n)ϕ(n),并且 e 与 ϕ(n)ϕ(n) 要互质
- 计算出一个整数 d,使得 (ed−1) % ϕ(n)=0(ed−1) % ϕ(n)=0,即 e∗de∗d 除以 ϕ(n)ϕ(n) 的余数为 1,实际上转化为找到二元一次方程 ed+kϕ(n)=1ed+kϕ(n)=1 的一组解(求 d 和 k),具体使用的是扩展欧几里得算法
于是我们可以得到:
- 公钥 (n, e)
- 私钥 (n, d)
在这样的条件下,如果想要根据 n 和 e 算出 d,就只能暴力破解,位数越长,玻璃破解时间越长。
加密
我们现在有个这么几个关键的数值:n, e, d。要使用公钥 (n, e) 加密,首先要求被加密的数字必须是整数且小于 n(如果是字符串,可以逐个取 ascii 码或 unicode 值,并且中间用非数字和字母分割即可)。假设我们需要加密的数字是 A,则加密之后的 B 为(为了区别使用大写):
Ae % n=BAe % n=B
如果没有 d,那么是很难从 B 中恢复 A 的。
解密
如果我们拥有私钥 (n, d),那么对于 B,就可以通过下面的公式计算出 A:
Bd % n=ABd % n=A
乘法同态
相对 Paillier 来说还要更加简单一些,我们只要把两个加密后的数字相乘即可,代码片段如下:
print('接下来加密计算 2 x 20')
print('加密 2')
enc1 = rsa.core.encrypt_int(2, public_key.e, public_key.n)
print(enc1)
print('加密 20') # 40471062776583530669631608186743860028386032505372124150562694293213549812024
enc2 = rsa.core.encrypt_int(20, public_key.e, public_key.n)
print(enc2) # 16915103439566807805446086181091224947678993169521653470724152014464992293178
print('相乘')
result = enc1 * enc2
print(result) # 684572213175112282577113686759405066981454950839007710126450052851088805616753069318980764721622690261112227625923822693220128510206043466290770597572272
print('解密结果')
decrypt_result = rsa.core.decrypt_int(result, private_key.d, public_key.n)
print(decrypt_result) # 40
写在最后
这一讲我们结合实际的例子熟悉了同态加密,接下来我们会继续介绍联邦学习相关的底层技术,让大家知其然更知其所以然。
参考链接
- 知乎:同态加密的实现原理是什么?在实际中有何应用?
- Paillier同态加密的介绍以及c++实现
- Paillier Python 包
- Pailler 论文原文
- RSA 算法原理 (一) (二)
- RSA算法原理简介
- 深入理解RSA算法
- RSA乘法同态加密的python实现
相关文章
- 【联邦学习之旅】01 联邦学习简介
- 【联邦学习之旅】02 联邦金融评分卡
- 【联邦学习之旅】04 不经意传输、秘密共享、密钥交换与差分隐私
- 【联邦学习之旅】B1 《联邦学习》读书笔记
- 【联邦学习之旅】C1 FATE Flow 流程源码解析
同态加密与 Paillier/RSA的更多相关文章
- Paillier同态加密实现
一.C++(该方案只实现了加密以及解密) 1.git clone https://github.com/klei0229/paillier.git 2.下载GMP与NTL包: 下载版本以及操作参见ht ...
- 同态加密-Homomorphic encryption
同态加密(Homomorphic encryption)是一种加密形式,它允许人们对密文进行特定的代数运算得到仍然是加密的结果,将其解密所得到的结果与对明文进行同样的运算结果一样.换言之,这项技术令人 ...
- RSA加密解密及RSA加签验签
RSA安全性应用场景说明 在刚接触RSA的时候,会混淆RSA加密解密和RSA加签验签的概念.简单来说加密解密是公钥加密私钥解密,持有公钥(多人持有)可以对数据加密,但是只有持有私钥(一人持有)才可以解 ...
- 加密解密 AES RSA MD5 SHA
加密解密: 对称加密:加密和解密相同秘钥.常见算法:AES, XTEA, 3DES. 非对称加密: 公钥加密 私钥加密. 加密和解密秘钥不同.常见算法:RSA OpenSSL> genrsa - ...
- RSA加密解密及RSA签名和验证及证书
RSA加密解密及RSA签名和验证及证书 公钥是给别人的 发送密文使用公钥加密 验证签名使用公钥验证 私钥是自己保留的 接受密文使用私钥解密 发送签名使用私钥签名 上述过程逆转是不行的,比如使用私钥加密 ...
- 【云安全与同态加密_调研分析(8)】同态加密技术及其应用分析——By Me
◆同态加密技术(Homomorphic Encryption, HE)及其应用◆ ◆加密方案◆ ◆应用领域◆ ◆厂商◆ ◆同态加密现有产品形态和工程实现◆ ◆参考链接◆ ◆备注(其他参考信息)◆ 同态 ...
- (转)对称加密与非对称加密,以及RSA的原理
一 概述 二对称加密和非对称加密 对称加密 非对称加密 区别 三RSA原理 整数运算 同余运算 当模数为合数n时 当模数为质数p的时候 离散对数问题 RSA原理 一 , 概述 在现代密码学诞生以前,就 ...
- RSA加密解密及RSA签名和验证
原文:RSA加密解密及RSA签名和验证 1.RSA加密解密: (1)获取密钥,这里是产生密钥,实际应用中可以从各种存储介质上读取密钥 (2)加密 (3)解密2.RSA签名和验证 (1)获取密钥,这里是 ...
- Paillier同态加密的介绍以及c++实现
我们先来简短认识一下Paillier同态加密算法: 如果就这么按照定义来用最简朴的c++程序写 就像这样: #include <iostream> #include <math.h& ...
随机推荐
- leetcode5225最大相等频率
题目 正整数数组nums,找到满足条件的最长前缀,返回其长度.该前缀满足:删除一个元素后,剩下的每个数字出现的次数相同. ps:如果删除后没有元素存在,也可以认为每个数字有相同的次数. 数组长度:[2 ...
- idea使用教程-idea简介
集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,一般包括代码编辑器.编译器.调试器和图形用户界面等工具.集成了代码编写功 ...
- Java初学者作业——编写Java程序, 实现根据用户购买商品总金额, 计算实际支付的金额及所获得的购物券金额。
返回本章节 返回作业目录 需求说明: 编写Java程序, 实现根据用户购买商品总金额, 计算实际支付的金额及所获得的购物券金额. 购买总金额达到或超过 1000元,按 8折优惠,送 200元的购物券: ...
- Window/Linux下Mysql的安装步骤
Windows下Mysql安装教程 首先讲一下Windows环境下安装Mysql,我使用的安装包版本是mysql-8.0.26-winx64 下载地址:MySQL下载 1.点击上面的下载地址得到zip ...
- Go项目开源规范
我们为什么一定要知道开源规范呢? 一是,开源项目在代码质量.代码规范.文档等方面,要比非开源项目要求更高,在项目开发中按照开源项目的要求来规范自己的项目,可以更好地驱动项目质量的提高: 二是,一些大公 ...
- Python_issubclass&isinstance方法和types&inspect内置模块
issubclass&isinstance issubclass 用于判断一个类是否是一个已知类或是该已知类的子类.注意,该方法只能判断类不能判断实例化对象. class A: pass cl ...
- lombok不支持enum类型
今天在使用枚举时想着少写getter方法和构造方法,结果加上注解后说是只支持class类型 来自为知笔记(Wiz)
- CentOS7 常用命令汇总
原文链接:https://blog.csdn.net/weixin_42208959/article/details/107970958 目录常用命令1.进程相关命令1.1 查询进程和结束进程1.2 ...
- Nagios 请检查HTTP服务器关于该CGI的访问权限设置
无权查看任何主机的信息. 请检查HTTP服务器关于该CGI的访问权限设置. 搜索了一下方法 确保 htpasswd.user的所有组为nagios 解决办法: vi /usr/local/nagios ...
- 第10组 Alpha冲刺 (6/6)
1.1基本情况 ·队名:今晚不睡觉 ·组长博客:https://www.cnblogs.com/cpandbb/p/14008187.html ·作业博客:https://edu.cnblogs.co ...