白话同态加密

虽然同态加密即使现在听起来也很陌生,但是其实这个概念来自 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 个小时),我拿到加密计算的结果再解密得到真实结果。那么问题来了,这个过程需要几步?

  1. 我在本地生成用来加密数据的 Key
  2. 我用 Key 和 Encrypt 算法加密本地的数据,记为 EncData = Encrypt(Key, Data)
  3. 我告诉云平台需要如何计算数据,记为函数 F()
  4. 云平台进行计算 Evaluate,即 Evaluate(F(), EncData) = Encrypt(Key, F(Data)),记为 ProEncData
  5. 云平台将 ProEncData 发回给我
  6. 我用密钥进行解密 Decrypt,得到 F(Data) = Decrypt(Key, ProEncData),也就是最终结果

在以上六个步骤中,至少有四个函数是必须的:

  1. 生成密钥的函数:本地执行,生成密钥
  2. Encrypt 函数:本地执行,加密数据,加密之后的数据不会暴露源数据的信息
  3. Evaluate 函数:用来执行用户给定的计算函数 F(),是唯一由云平台运行的函数
  4. Decrypt 函数:本地执行,解密数据

根据支持的 F() 的不同,同态加密分成了两类:

  1. Fully Homomorphic Encryption, FHE:这种方式下,任何 F() 都可以,只要这个算法能够被计算机实现即可。不过这个计算开销非常大,目前暂无实际应用。注:Gentry 在 2009 年给出过一个实现

  2. Somewhat Homomorphic Encryption, SWHE:这种方式下,只支持某些特定的

    F()

    (比如只支持加法/乘法,并且只能执行有限次数)。这个方案有比较大的限制,但也因此计算开销较小,已经可以在实际中使用

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

接下来我们会详细看看 Paillier 算法和 RSA 算法,对加法同态和乘法同态有更加深入的理解。

Paillier 算法

因为有了前面的分析,我们知道一个同态加密算法需要四个函数:密钥生成、加密、解密、同态运算,针对 Paillier 算法,我们一项一项来看一下。

这里我们也准备了不同语言版本的实例:

  1. Python 版
  2. Golang 版

注:实际实现的过程中,一般不会直接实现 gcd 和 lcm 函数,而是采用一些替代的计算,具体参考上面链接中的源码。

密钥生成

总共有如下几个步骤:

  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 加密方案具有加法同态性。

RSA 算法

RSA 算法作为最为知名的非对称加密算法,想必大家都有一定的了解,这里我们仍然以针对密钥生成、加密、解密、同态运算四个步骤,一项一项来看一下。同样可以参考下面的代码实例:

  1. Python 版

密钥生成

  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

写在最后

这一讲我们结合实际的例子熟悉了同态加密,接下来我们会继续介绍联邦学习相关的底层技术,让大家知其然更知其所以然。

参考链接

相关文章

同态加密与 Paillier/RSA的更多相关文章

  1. Paillier同态加密实现

    一.C++(该方案只实现了加密以及解密) 1.git clone https://github.com/klei0229/paillier.git 2.下载GMP与NTL包: 下载版本以及操作参见ht ...

  2. 同态加密-Homomorphic encryption

    同态加密(Homomorphic encryption)是一种加密形式,它允许人们对密文进行特定的代数运算得到仍然是加密的结果,将其解密所得到的结果与对明文进行同样的运算结果一样.换言之,这项技术令人 ...

  3. RSA加密解密及RSA加签验签

    RSA安全性应用场景说明 在刚接触RSA的时候,会混淆RSA加密解密和RSA加签验签的概念.简单来说加密解密是公钥加密私钥解密,持有公钥(多人持有)可以对数据加密,但是只有持有私钥(一人持有)才可以解 ...

  4. 加密解密 AES RSA MD5 SHA

    加密解密: 对称加密:加密和解密相同秘钥.常见算法:AES, XTEA, 3DES. 非对称加密: 公钥加密 私钥加密. 加密和解密秘钥不同.常见算法:RSA OpenSSL> genrsa - ...

  5. RSA加密解密及RSA签名和验证及证书

    RSA加密解密及RSA签名和验证及证书 公钥是给别人的 发送密文使用公钥加密 验证签名使用公钥验证 私钥是自己保留的 接受密文使用私钥解密 发送签名使用私钥签名 上述过程逆转是不行的,比如使用私钥加密 ...

  6. 【云安全与同态加密_调研分析(8)】同态加密技术及其应用分析——By Me

    ◆同态加密技术(Homomorphic Encryption, HE)及其应用◆ ◆加密方案◆ ◆应用领域◆ ◆厂商◆ ◆同态加密现有产品形态和工程实现◆ ◆参考链接◆ ◆备注(其他参考信息)◆ 同态 ...

  7. (转)对称加密与非对称加密,以及RSA的原理

    一 概述 二对称加密和非对称加密 对称加密 非对称加密 区别 三RSA原理 整数运算 同余运算 当模数为合数n时 当模数为质数p的时候 离散对数问题 RSA原理 一 , 概述 在现代密码学诞生以前,就 ...

  8. RSA加密解密及RSA签名和验证

    原文:RSA加密解密及RSA签名和验证 1.RSA加密解密: (1)获取密钥,这里是产生密钥,实际应用中可以从各种存储介质上读取密钥 (2)加密 (3)解密2.RSA签名和验证 (1)获取密钥,这里是 ...

  9. Paillier同态加密的介绍以及c++实现

    我们先来简短认识一下Paillier同态加密算法: 如果就这么按照定义来用最简朴的c++程序写 就像这样: #include <iostream> #include <math.h& ...

随机推荐

  1. World is Exploding(hdu5792)

    World is Exploding Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  2. P1753HackSon的趣味题

    1 #include<stdio.h> 2 #include<algorithm> 3 #include<iostream> 4 #include<stdli ...

  3. 用户线程&&守护线程

         守护线程是为用户线程服务的,当一个程序中的所有用户线程都执行完成之后程序就会结束运行,程序结束运行时不会管守护线程是否正在运行,由此我们可以看出守护线程在 Java 体系中权重是比较低的.当 ...

  4. 「Codeforces 724F」Uniformly Branched Trees

    题目大意 如果两棵树可以通过重标号后变为完全相同,那么它们就是同构的. 将中间节点定义为度数大于 \(1\) 的节点.计算由 \(n\) 个节点,其中所有的中间节点度数都为 \(d\) 的互不同构的树 ...

  5. Log4j使用的方法

    一.什么是log4j Log4J是Apache的一个开放源代码的项目.通过使用Log4J,程序员可以控制日志信息输送的目的地,包括控制台,文件,GUI组件和NT事件记录器,也可以控制每一条日志的输出格 ...

  6. Unsupervised Domain Adaptation by Backpropagation

    目录 概 主要内容 代码 Ganin Y. and Lempitsky V. Unsupervised Domain Adaptation by Backpropagation. ICML 2015. ...

  7. Intriguing Properties of Contrastive Losses

    目录 概 主要内容 广义对比损失 不同的先验 不同的权重比 Feature Suppression DigitOnImageNet dataset RandBit dataset 代码 [Chen T ...

  8. Not All Samples Are Created Equal: Deep Learning with Importance Sampling

    目录 概 主要内容 "代码" Katharopoulos A, Fleuret F. Not All Samples Are Created Equal: Deep Learnin ...

  9. MA8601升级版 PL2586|USB HUB 工控级芯片方案PL2586|可直接替代FE1.1S芯片方案

    MA8601升级版 PL2586|USB HUB 工控级芯片方案PL2586|可直接替代FE1.1S芯片方案 旺玖在2022年新推出的一款USB HUB 芯片其性能和参数可以完全替代FE1.1S,是M ...

  10. 基于node和npm的命令行工具——tive-cli

    前端开发过程中经常会用到各种各样的脚手架工具.npm全局工具包等命令行工具,如:Vue脚手架@vue/cli.React脚手架create-react-app.node进程守卫工具pm2.本地静态服务 ...