同态加密(Homomorphic Encryption)是很久以前密码学界就提出来的一个问题。早在1978年,Ron Rivest, Leonard Adleman, 以及Michael L. Dertouzos就以银行为应用背景提出了这个概念。其中Ron Rivest和Leonard Adleman分别就是著名的RSA算法中的R和A。

同态加密是基于数学难题的计算复杂性理论的密码学技术。对经过同态加密的数据进行处理得到一个输出,将这一输出进行解密,其结果与用同一方法处理未加密的原始数据得到的输出结果是一样的。

第一个构造出全同态加密(Fully Homomorphic Encryption)的Craig Gentry给出的直观定义是:一种不需要访问数据本身就可以加工数据的方法

同态加密的具体过程

同态加密算法有哪些 同态加密的定义_数据

 以云计算应用场景为例,Alice通过Cloud,以同态加密处理数据的整个处理过程大致是这样的:

  1. Alice对数据进行加密。并把加密后的数据发送给Cloud;
  2. Alice向Cloud提交数据的处理方法,这里用函数f来表示;
  3. Cloud在函数f下对数据进行处理,并且将处理后的结果发送给Alice;
  4. Alice对数据进行解密,得到结果。

据此,我们可以很直观的得到一个HE方案应该拥有的函数:

  • KeyGen函数:密钥生成函数。这个函数应该由Alice运行,用于产生加密数据Data所用的密钥Key。同时应该还有一些公开常数PP(Public Parameter);
  • Encrypt函数:加密函数。这个函数也应该由Alice运行,用Key对用户数据Data进行加密,得到密文CT(Ciphertext);
  • Evaluate函数:评估函数。这个函数由Cloud运行,在用户给定的数据处理方法f下,对密文进行操作,使得结果相当于用户用密钥Key对f(Data)进行加密。
  • Decrypt函数:解密函数。这个函数由Alice运行,用于得到Cloud处理的结果f(Data)。

根据f的限制条件不同,HE方案实际上分为了两类:

  • Fully Homomorphic Encryption (FHE):这意味着HE方案支持任意给定的f函数,只要这个f函数可以通过算法描述,用计算机实现。显然,FHE方案是一个非常棒的方案,但是计算开销极大,暂时还无法在实际中使用。
  • Somewhat Homomorphic Encryption (SWHE):这意味着HE方案只支持一些特定的f函数。SWHE方案稍弱,但也意味着开销会变得较小,容易实现,现在已经可以在实际中使用。

算法:

  1. 乘法:RSA, Elgamal
  2. 加法:Paillier

Paillier同态加密算法:

密钥生成

总共有如下几个步骤:

  1. 随机选择两个质数 p 和 q 满足 |p|=|q|=τ|p|=|q|=τ,这个条件保证了 p 和 q 的长度相等。
  2. 计算 N=pqN=pq 和 λ=lcm(p−1,q−1)λ=lcm(p−1,q−1),注:lcm 表示最小公倍数
  3. 随机选择 g∈Z∗N2g∈ZN2∗,满足 gcd(L(gλmodN2),N)=1gcd(L(gλmodN2),N)=1,注:gcd 表示最大公约数;Z 表示整数,下标表示该整数集合里有多少个元素;L(x)=x−1NL(x)=x−1N
  4. 公钥为 (N,g)(N,g)
  5. 私钥为 λλ

加密

对于任意整数 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 加密方案具有加法同态性。

Paillier同态加密算法的python实现:

from phe import paillier # 开源库
import time # 做性能测试

# 测试paillier参数
print("默认私钥大小:",paillier.DEFAULT_KEYSIZE) #2048
# 生成公私钥
public_key,private_key = paillier.generate_paillier_keypair()
# 测试需要加密的数据
message_list = [3.1415926,100]
# 加密操作
time_start_enc = time.time()
encrypted_message_list = [public_key.encrypt(m) for m in message_list]
time_end_enc = time.time()
print("加密耗时ms:",time_end_enc-time_start_enc)
# 解密操作
time_start_dec = time.time()
decrypted_message_list = [private_key.decrypt(c) for c in encrypted_message_list]
time_end_dec = time.time()
print("解密耗时ms:",time_end_dec-time_start_dec)
print("原始数据:",decrypted_message_list)

a1,b1 = message_list           # a1,b1分别为对应原始数据
# 测试加法和乘法同态
a2,b2 = encrypted_message_list # a2,b2分别为对应密文

print("a1 a2 = ", a1, a2)
print("b1 b2 = ", b1, b2)
#密文加明文
print("a1+5=", a1+5, ",dec(a2+5)=", private_key.decrypt(a2+5))
#密文加密文
print("a1+b1=", a1+b1, ",dec(a2+b2)=", private_key.decrypt(a2+b2))
#密文乘明文
print("a1*2 = ", a1*2, ",dec(a2*2) = ", private_key.decrypt(a2*2))
#密文乘密文(不支持)
print("a1*b1 = ", a1*b1, ",dec(a2*b2) = ", private_key.decrypt(a2*b2))

结果打印: 

默认私钥大小: 2048

加密耗时ms: 0.19597172737121582

解密耗时ms: 0.062391042709350586

原始数据: [3.1415926, 100]

a1 a2 =  3.1415926 <phe.paillier.EncryptedNumber object at 0x102def790>

b1 b2 =  100 <phe.paillier.EncryptedNumber object at 0x102cfd400>

a1+5= 8.1415926 ,dec(a2+5)= 8.1415926

a1+b1= 103.1415926 ,dec(a2+b2)= 103.1415926

a1*2 =  6.2831852 ,dec(a2*2) =  6.2831852

Traceback (most recent call last):

  File "test.py", line 37, in <module>

    print("a1*b1 = ", a1*b1, ",dec(a2*b2) = ", private_key.decrypt(a2*b2))

  File "/usr/local/lib/python3.8/site-packages/phe/paillier.py", line 498, in __mul__

    raise NotImplementedError('Good luck with that...')

NotImplementedError: Good luck with that...

RSA同态加密算法:

密钥生成

  1. 随机找两个质数 P 和 Q,越大越安全,并计算乘积 n=P∗Qn=P∗Q。P 和 Q 的乘积的二进制位数代表 RSA 加密的位数,一般来说都要有 1024 或 2048 位。
  2. 计算 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)
  3. 选取 e,要大于 1 小于 ϕ(n)ϕ(n),并且 e 与 ϕ(n)ϕ(n) 要互质
  4. 计算出一个整数 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

同态加密的安全性

HE方案的最基本安全性是语义安全性(Semantic Security)。直观地说,就是密文(Ciphertext)不泄露明文(Plaintext)中的任意信息。如果用公式表述的话,为:

同态加密算法有哪些 同态加密的定义_数据_02


这里PK代表公钥(Public Key),公式中的"约等于"符号,意味着多项式不可区分性,即不存在高效的算法,可以区分两个结果,即使已知m0, m1和PK。这是因为加密算法中还用到一个很重要的量:随机数。也就是说,对于同样的明文m进行加密,得到的结果都不一样,即一个明文可以对应多个密文(many ciphertexts per plaintext)。

在密码学中,还有更强的安全性定义,叫做选择密文安全性(Chosen Ciphertext Security)。选择密文安全性分为非适应性(None-Adaptively)和适应性(Adaptively),也就是CCA1和CCA2。HE方案是不可能做到CCA2安全的。那么,HE方案能不能做到CCA1安全呢?至今还没有CCA1安全的FHE方案,但是在2010年,密码学家们就已经构造出了CCA1的SWHE方案了。

HE方案还有一方面的安全性,就是函数f是否也可以保密?如果能保密,Cloud不仅不能够得到数据本身的内容,现在连数据怎么处理的都不知道,只能按照给定的算法执行,然后返回的结果就是用户想要的结果。如果HE方案满足这样的条件,我们称这个HE方案具有Function-Privacy特性。不过,现在还没有Function-privacy FHE,甚至Function-privacy SWHE也没有。

同态加密的实现与效率 

FHE最重要的一点是Fully,就是说要支持任意的函数f。因此我们也可以很明显看出,想要构造FHE,就需要了解计算机是如何计算的。一般来说,我们有两种思路:

  • 从计算机原理考虑。计算机无论做何种运算,归根到底都是位运算。实际上,一个计算机只要支持逻辑与运算(AND),以及异或运算(XOR),那么这个计算机理论上就可以实现计算机的其他运算了(我们称之为图灵完备性,Turing Completeness)
  • 从抽象代数考虑。我们只需要加法和乘法就可以完成全部运算了。但其实更严格的说,只要我们在一个域(Field)上构造HE,理论上我们就可以支持所有的f。

同态加密的应用

同态加密技术在分布式计算环境下的密文数据计算方面具有比较广泛的应用领域,比如云计算、多方保密计算、匿名投票等

1、安全云计算与委托计算

同态技术在该方面的应用可以使得我们在云环境下,充分利用云服务器的计算能力,实现对明文信息的运算,而不会有损私有数据的私密性。例如医疗机构通常拥有比较弱的数据处理能力,而需要第三方来实现数据处理分析以达到更好的医疗效果或者科研水平,这样他们就需要委托有较强数据处理能力的第三方实现数据处理(云计算中心),但是医院负有保护患者隐私的义务,不能直接将数据交给第三方。在同态加密技术的支持下,医疗机构就可以将加密后的数据发送至第三方,待第三方处理完成后便可返回给医疗结构。整个数据处理过程、数据内容对第三方是完全透明的。

2、文件存储与密文检索

用户可以将自己的数据加密后存储在一个不信任的远程服务器上,日后可以向远程服务器查询自己所需要的信息,存储与查询都使用密文数据,服务器将检索到的密文数据发回。用户可以解密得到自己需要的信息,而远程服务器却对存储和检索的信息一无所知。此种方法同样适用于搜索引擎的数据检索。

3、安全多方计算协议设计的工具

所谓安全多方计算就是分别持有私有数据 x1,x2,…,xn的 n 个人,在分布式环境中协同计算函数f (x1,x2,…,xn) 而不泄露各方的私有数据。以同态技术加密的密文数据计算不仅可以满足安全多方计算协议设计中保护各方隐私的需要,还能避开不经意传输协议而大大提升协议效率。

4、电子选举

基于同态加密技术设计的电子选举方案,统计方可以在不知道投票者投票内容的前提下,对投票结果进行统计,既保证了投票者的隐私安全,有能够保证投票结果的公证。